-1

我正在尝试理解 java 通用通配符。我遇到了一个基本程序。在我看来,唯一可以添加到列表 s 中的是“null”。例如,您不能添加

s.add(new Integer (4)); 

OR

s.add(new Char(a));

在阅读大量材料并混淆我的思想之前,我试图了解 Java 设计人员在泛型中引入通配符的目的。从我的角度来看,我看不到任何有用的特性来自泛型通配符。它可能出现所以由于我缺乏经验并且因为我是java新手。如果人们可以分享他们对此事的想法会很好。

import java.util.LinkedList;
import java.util.Iterator;

public class WildCardExampleOne {

    public static void main(String[] args)
    {
        LinkedList<?> s = new LinkedList<Integer>();
        s.add(null);

        Iterator<?> x = s.iterator();

        Object o = x.next();

        System.out.println(o);

        /* note that LinkedList<?> is NOT the same type as LinkedList<Object>
         * here are some statements that wouldn't compile:
         */
        // s.add(new Integer(3)); 
        // Iterator<Object> x = s.iterator();
    }
}
4

4 回答 4

6

在我看来,唯一可以添加到列表 s 中的是“null”。

是的,这是正确的。但是,您经常会收到一个不需要(也不应该)添加任何元素的列表。例如,考虑一个将列表元素打印到标准输出的简单方法,每行一个:

public static void printAll(final List<?> list) {
    for (final Object elem : list) {
        System.out.println(elem);
    }
}

这个方法不需要知道列表的元素类型是什么;它可以在 a List<String>、 an ArrayList<Integer>、 aLinkedList<Object>或任何其他上调用List<?>

于 2013-08-09T01:57:25.733 回答
2

您不会使用通配符直​​接实例化泛型类;您使用 is 与extendsor结合使用super

于 2013-08-09T01:55:48.110 回答
2

@chylis 是对的,只是为了补充他/她的评论,我会试着用简单的话来表达:当然,通配符不允许你使用像 setter 这样的方法,但它们会让你做这样的事情:

public void doSomethingWithList(List<? extends Number> list) {

    for(Number number: list) {

        // do something with number

    }

}

您可以将 List<Integer>、List<Long>、List<Float> 等与此方法一起使用doSomethingWithList(),并且您肯定会知道您正在处理 a Number(并使用compareTo()等方法),如果您只需使用没有通配符的泛型,您就必须使用相同的方法执行类似的操作:

public void doSomethingWithList(List<?> list) {

    for(Object number: list) {
        Number myNumber = (Number)number; // UNSAFE
    }

}
于 2013-08-09T02:04:03.457 回答
1

查看泛型的 java 文档:http: //docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

这个想法是您可以将它们用于方法类型:(Collection<?>发音为“未知集合”)是方法的超类型。

它让你从这个出发:

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

对此:

void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}

WhereCollection<?>允许您安全地从中读取元素,但不允许您安全地将元素存储到其中。

它真正让你受益的地方是采取这样的措施:

public void drawAll(List<Shape> shapes) {
    for (Shape s: shapes) {
        s.draw(this);
    }
}

并将其重写为如下内容:

public void drawAll(List<? extends Shape> shapes) {
    ...
}

Cicle如果class Circle extends Shape. _

希望这对您理解泛型有所帮助。

于 2013-08-09T02:03:53.993 回答