Consider the following program:
public class GenericTypeInference {
public static void main(String[] args) {
First of all it has nothing to do with overriding , but it has to deal with overloading.
Jls,. Section 15 provides lot of information on how exactly compiler selects the overloaded method
The most specific method is chosen at compile time; its descriptor determines what method is actually executed at run time.
So when invoking
print(new SillyGenericWrapper().get());
The compiler choose String
version over Object
because print
method that takes String
is more specific then the one that takes Object
. If there was Integer
instead of String
then it will get selected.
Moreover if you want to invoke method that takes Object
as a parameter then you can assign the return value to the parameter of type object
E.g.
public class GenericTypeInference {
public static void main(String[] args) {
final SillyGenericWrapper sillyGenericWrapper = new SillyGenericWrapper();
final Object o = sillyGenericWrapper.get();
print(o);
print(sillyGenericWrapper.get());
}
private static void print(Object object) {
System.out.println("Object");
}
private static void print(Integer integer) {
System.out.println("Integer");
}
public static class SillyGenericWrapper {
public T get() {
return null;
}
}
}
It outputs
Object
Integer
The situation starts to become interesting when let say you have 2 valid method definations that are eligible for overloading. E.g.
private static void print(Integer integer) {
System.out.println("Integer");
}
private static void print(String integer) {
System.out.println("String");
}
and now if you invoke
print(sillyGenericWrapper.get());
The compiler will have 2 valid method definition to choose from , Hence you will get compilation error because it cannot give preference to one method over the other.