有人能解释一下使用以下方法的区别吗:
<T extends Object> void method(T input){
}
只有
void method(Object input){
}
据我所知,在这两种情况下,我们在运行时都有Object类型。使用有界泛型的好处是什么?
为什么认为有好处?第一个只是第二个更详细的形式,就像1+1+1+1+1是一种更详细的表达5的方式。
拥有它的方式没有区别。
但是,结构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");
}
这很糟糕。我可以将运行时检查移到编译时间检查,所以你可以天真地做:
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
,和以前一样。