我正在阅读OracleDocGenericMethod的泛型方法。当它说何时使用通配符以及何时使用泛型方法时,我对比较感到非常困惑。从文档中引用。
interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); }
我们可以在这里使用泛型方法:
interface Collection<E> { public <T> boolean containsAll(Collection<T> c); public <T extends E> boolean addAll(Collection<T> c); // Hey, type variables can have bounds too! }
[…] 这告诉我们类型参数被用于多态性;它的唯一作用是允许在不同的调用站点使用各种实际的参数类型。如果是这种情况,应该使用通配符。通配符旨在支持灵活的子类型化,这就是我们在这里想要表达的。
难道我们不认为通配符之类(Collection<? extends E> c);
的也支持某种多态性吗?那么为什么泛型方法的使用在这方面被认为不好呢?
继续前进,它指出,
泛型方法允许使用类型参数来表达方法和/或其返回类型的一个或多个参数的类型之间的依赖关系。如果不存在这样的依赖关系,则不应使用泛型方法。
这是什么意思?
他们提出了这个例子
class Collections { public static <T> void copy(List<T> dest, List<? extends T> src) { ... }
[…]
我们可以用另一种方式为这个方法编写签名,根本不使用通配符:
class Collections { public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... }
该文件不鼓励使用第二个声明并提倡使用第一个语法?第一次和第二次声明有什么区别?两者似乎都在做同样的事情?
有人可以照亮这个区域吗?