何时使用泛型方法,何时使用通配符?
我正在阅读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) { ... }
该文档不鼓励第二种声明,并促进使用第一种语法?第一个声明和第二个声明有什么区别?两者似乎都在做同样的事情?
有人可以在这个区域放光吗?