有界泛型类型和父类型之间有什么区别?

时间:2020-10-30 16:25:42

标签: java generics

任何人都可以解释使用以下方法有何区别:

<T extends Object> void method(T input){
}

还有

void method(Object input){
}

据我了解-在两种情况下,我们在运行时都具有对象类型。 使用有界泛型有什么好处?

2 个答案:

答案 0 :(得分:2)

您为什么认为有好处?第一个只是第二个的更详细的形式,例如1 + 1 + 1 + 1 + 1是表示5的更详细的方式。

答案 1 :(得分:1)

您拥有它的方式没有什么

但是,构造T extends Object是在其他“功能”的上下文中使用的。当我重构某些代码时,有时会强制使用它。想象一下这种方法(是的,我们在某个时间点的生产环境中就有这样的代码):

public static <T> int sizeOfList(T obj) {
    if (obj instanceof List) {
        return ((List) obj).size();
    }

    throw new IllegalArgumentException("only list is supported");
} 

不好。我可以将 runtime 检查移至 compile 时间检查,因此您可以天真地做到这一点:

public static <T extends List<?>> int sizeOfList(T obj) {
    return obj.size();
}

但是这里有一个细微的问题。第一种方法中T擦除Object,第二种方法中的擦除是List。因此,现在相同的调用者(如果他们不重新编译的话)也会遇到一个令人讨厌的惊喜:java.lang.NoSuchMethodError

要摆脱这种情况(在重构后人们会讨厌我),我这样做:

public static <T extends Object & List<?>> int sizeOfList(T obj) {
    return obj.size();
}

编译时间的安全性仍然存在,但擦除操作已处于第一个界限:Object,与以前一样。

相关问题