问题 泛型是否绑定了Java中方法签名的一部分?


我今天意识到这个编译运行正常:

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

泛型绑定被认为是方法签名的一部分吗?或者它是一种方法重载决议魔术?


6516
2017-07-20 18:08


起源

简而言之: <T extends String> 被删除了 String虽然只是 <T> 被删除了 Object 所以编译器会创建两个重载方法: handle(Object) 和 handle(String) 在其他地方,可以根据参数类型选择这些方法。 - Pshemo
关于这个主题的官方教程: 删除通用方法 - Pshemo


答案:


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

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 (记住 String 是最后的,没有孩子)。


11
2017-07-20 18:12





考虑了泛型的界限。

在第一种情况下,绑定是Object;在第二种情况下,绑定是String。

当类型被擦除时,使用绑定代替类型变量,因此这些只是分别过载(和返回)Object和String参数。

没有错。


2
2017-07-20 18:13