【问题标题】:Is generics bound part of method signature in Java?泛型是Java中方法签名的一部分吗?
【发布时间】:2018-07-20 18:08:41
【问题描述】:

我今天意识到这编译并运行良好:

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

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

【问题讨论】:

  • 简而言之:&lt;T extends String&gt; 被擦除为String,而只有&lt;T&gt; 被擦除为Object,因此编译器将创建两个重载方法:handle(Object)handle(String) 以及其他可以根据参数类型选择这些方法的位置。

标签: java generics overload-resolution


【解决方案1】:

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

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 是最终的,不能有子级) .

【讨论】:

    【解决方案2】:

    考虑泛型的界限。

    在第一种情况下,边界是Object;在第二种情况下,边界是字符串。

    当类型被擦除时,使用边界来代替类型变量,所以它们变成了简单的重载,分别接受(和返回)对象和字符串参数。

    没有错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多