Java泛型:通配符

Java泛型:通配符,java,generics,Java,Generics,所以我在阅读泛型以重新熟悉这些概念,尤其是通配符,因为我几乎从未使用过或遇到过通配符。从我的阅读中,我不明白他们为什么使用通配符。下面是我经常遇到的一个例子 void printCollection( Collection<?> c ) { for (Object o : c){ System.out.println(o); } } void printCollection(集合c){ 用于(对象o:c){ 系统输出打印ln(o); } } 你为什么不把它写成:

所以我在阅读泛型以重新熟悉这些概念,尤其是通配符,因为我几乎从未使用过或遇到过通配符。从我的阅读中,我不明白他们为什么使用通配符。下面是我经常遇到的一个例子

void printCollection( Collection<?> c ) {
  for (Object o : c){
    System.out.println(o);
  }
}
void printCollection(集合c){
用于(对象o:c){
系统输出打印ln(o);
}
}
你为什么不把它写成:

<T> void printCollection( Collection<T> c ) {
    for(T o : c) {
        System.out.println(o);
    }
}
<T> void printCollection( Collection<T> c ) {
    for(T o : c) {
        System.out.println(o);
    }
}
void printCollection(集合c){
对于(TO:c){
系统输出打印ln(o);
}
}
oracle网站上的另一个示例:

public static double sumOfList(List<? extends Number> list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}

publicstaticdoublesumoflist(List为什么要让事情变得比需要的更复杂?示例演示了–这些示例并不试图说明通用方法

你为什么不把它写成:

<T> void printCollection( Collection<T> c ) {
    for(T o : c) {
        System.out.println(o);
    }
}
<T> void printCollection( Collection<T> c ) {
    for(T o : c) {
        System.out.println(o);
    }
}

同样,因为您不需要为每个不同的
t扩展数
使用不同的参数化。一种接受
列表的非泛型方法,如果一个方法参数类型有一个带上限的一级通配符,则可以用一个类型参数替换它

反例(通配符不能被类型参数替换)

到目前为止的讨论是关于方法签名的。在其他地方,在不能引入类型参数的地方,通配符是必不可少的。

来自:

出现的一个问题是:什么时候应该使用泛型方法,什么时候应该使用通配符类型?为了理解答案,让我们检查一下集合库中的几个方法

接口集合{
公共图书馆(c组);

公共布尔加法(收集可能@Jayamohan我不同意。我想我可能只是误解了两者之间的区别,或者它们是一样的?我会遇到什么情况,不能用T而不是?来解决。我有一种感觉,我完全忽略了通配符的意义。@JonTaylor:没有任何情况是你不能解决的用
T
代替
,但关键是
不需要名称,这意味着您真的不在乎类型是什么。@LouisWasserman
Class.forName
返回
类可能只是一个通配符合适的例子。+1用于提及该类型参数。谢谢大家他解释得很好,但由于某种原因,这一解释帮助我理解得最多。
    List<?> foo()  // wildcard in return type  

    void foo(List<List<?>> arg)   // deeper level of wildcard

    void foo(List<? super Number> arg)   // wildcard with lower bound
        void foo1(List<?> arg)

    <T> void foo2(List<T> arg)
    <T> void foo(List<T> foo1, List<T> foo2);  // can't use 2 wildcards.
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!
 }