Can anyone explain in simple terms why in the below class, when I pass in a String, Integer or UUID, only the method overload taking Object as a parameter is used?
public final class SkuHydratingConverter implements Converter<Object, Sku> {
@Autowired
private SkuService skuService;
/**
* Default implementation, that errs as we don't know how to convert from
* the source type.
*/
public Sku convert(Object source) throws IllegalArgumentException {
throw new IllegalArgumentException("Could not convert to Sku");
}
public Sku convert(String source) throws IllegalArgumentException {
return convert(Integer.valueOf(source));
}
public Sku convert(Integer source) throws IllegalArgumentException {
return skuService.get(source);
}
public Sku convert(UUID source) throws IllegalArgumentException {
return skuService.get(source);
}
}
Originally I'd wanted to implement Converter<?, ?>
three times in the one class, but I soon discovered that's not possible.
The overloading mechanism works in compile time, that is, which method to call is decided when compiling the classes, not when you run the program.
Since runtime types can't (in general) be known at compile time, a snippet like this
Object o = "some string";
method(o);
will result in a call to a method
that takes an Object
as argument, as Object
is the compile-time type of o
.
(This has nothing to do with type-erasure or generics.)