I realized today that this compiles and runs fine:
public class Test {
public static <T> T handle(T val) {
System.out.println("T");
return val;
}
public static <T extends String> T handle(T val) {
System.out.println("T extends String");
return val;
}
}
The two handle
methods has the same name, and same number and type (?
) of parameters. The only difference is that the second handle
method has a stricter generic bound. IDE does not complain at all, and the code compiles fine. At run time method is selected as expected - e.g. Test.handle("this is a string")
will call into the second method and Test.handle(10)
will invoke the first one.
Is generics bound considered part of the method signature? or is it a method overload resolution magic?
Generics offer compile-time type-safety; At runtime, your methods erase to the following:
public static Object handle(Object val) {
System.out.println("T");
return val;
}
public static String handle(String val) {
System.out.println("T extends String");
return val;
}
Due to method overloading, handle(String)
will be called when passing a String
, and handle(Object)
will be called when passing any other Object
(keep in mind String
is final and can have no children).