我今天意识到这编译并运行良好:
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;
}
}
两个handle
方法具有相同的名称、相同数量和类型的参数(?
(。唯一的区别是第二种handle
方法具有更严格的泛型界。IDE一点也不抱怨,代码编译得很好。在运行时,按预期选择方法,例如Test.handle("this is a string")
将调用第二个方法,Test.handle(10)
将调用第一个方法。
泛型绑定是否被视为方法签名的一部分?还是说这是一种方法超负荷解析魔术?
泛型提供编译时类型安全;在运行时,您的方法会擦除到以下内容:
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;
}
由于方法重载,在传递String
时将调用handle(String)
,在传递任何其他Object
时将调用handle(Object)
(请记住,String
是最终的,不能有子级(。
考虑泛型的边界。
在第一种情况下,绑定是Object;在第二种情况下,绑定为String。
当类型被擦除时,绑定被用来代替类型变量,因此它们变成了一个分别接受(和返回(Object和String参数的重载。
这没什么错。