void printCollection( Collection<?> c ) { for (Object o : c){ System.out.println(o); } }
为什么你不写这个:
<T> void printCollection( Collection<T> c ) { for(T o : c) { System.out.println(o); } }
来自oracle网站的另一个例子:
public static double sumOfList(List<? extends Number> list) { double s = 0.0; for (Number n : list) s += n.doubleValue(); return s; }
为什么这不是写的
public static <T extends Number> double sumOfList(List<T> list) { double s = 0.0; for (Number n : list) s += n.doubleValue(); return s; }
我错过了什么吗?
解决方法
One question that arises is: when should I use generic methods,and when should I use wildcard types? To understand the answer,let’s examine a few methods from the Collection libraries.
interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); }
We could have used generic methods here instead:
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! }
However,in both containsAll and addAll,the type parameter T is used only once. The return type doesn’t depend on the type parameter,nor does any other argument to the method (in this case,there simply is only one argument). This tells us that the type argument is being used for polymorphism; its only effect is to allow a variety of actual argument types to be used at different invocation sites. If that is the case,one should use wildcards. Wildcards are designed to support flexible subtyping,which is what we’re trying to express here.
所以对于第一个例子来说,这是因为操作不依赖于类型.
对于第二个,这是因为它只取决于Number类.