泛型绑定是Java中方法签名的一部分吗?

时间:2018-07-20 18:08:41

标签: java generics overload-resolution

今天我意识到它可以编译并正常运行:

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)将调用第一个方法。

是否将泛型绑定视为方法签名的一部分?还是方法重载解析魔术?

2 个答案:

答案 0 :(得分:12)

泛型提供了编译时的类型安全性;在运行时,您的方法将擦除为以下内容:

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;
}

由于方法重载,传递handle(String)时将调用String,传递任何其他handle(Object)时将调用Object(请注意{{1 }}是最终的,不能有子代。

答案 1 :(得分:2)

要考虑泛型的界限。

在第一种情况下,边界是Object;在第二种情况下,边界是String。

擦除类型时,将使用边界代替类型变量,因此它们分别简单地成为一个重载,分别获取(和返回)Object和String参数。

没问题。