如果您的takeThing
方法需要向list
参数添加元素,则通配符版本将无法编译。
有趣的情况是当您没有添加到列表中并且两个版本似乎都可以编译和工作时。
在这种情况下,当您想在列表中允许不同类型的动物(更灵活)时,您将编写通配符版本,当您需要在列表中使用固定类型的动物时,您将编写参数版本:T 类型。
例如java.util.Collection
声明:
interface Collection<E> {
...
public boolean containsAll(Collection<?> c);
...
}
并假设您有以下代码:
Collection<Object> c = Arrays.<Object>asList(1, 2);
Collection<Integer> i = Arrays.<Integer>asList(1, 2, 3);
i.containsAll(c); //compiles and return true as expected
如果java.util.Collection
是:
interface Collection<E> {
...
public boolean containsAll(Collection<E> c);
...
}
上述测试代码将无法编译,Collection
API 的灵活性会降低。
值得注意的是,后者的定义containsAll
具有在编译时捕获更多错误的优势,例如:
Collection<String> c = Arrays.asList("1", "2");
Collection<Integer> i = Arrays.asList(1, 2, 3);
i.containsAll(c); //does not compile, the integer collection can't contain strings
但是错过了有效的测试Collection<Object> c = Arrays.<Object>asList(1, 2);