有人可以解释一下 mean和何时应该使用以及这种结构应该如何配合和?

我使用generics相当长的时间,但我从来没有使用像List List

这是什么意思? 如何使用它? 它如何看待擦除?

我也想知道:它是generics编程(模板编程?)中的标准还是它只是一个java’发明’? 例如,c#是否允许类似的结构?

如果要将集合中的项目用于另一个集合,则使用此构造。 例如,您有一个通用的Stack并且您想要添加一个popAll方法,该方法将Collection作为参数,并将堆栈中的所有项目弹出到其中。 根据常识,此代码应该是合法的:

 Stack numberStack = new Stack(); Collection objects = ... ; numberStack.popAll(objects); 

但只有在你定义popAll它才会编译:

 // Wildcard type for parameter that serves as an E consumer public void popAll(Collection dst) { while (!isEmpty()) dst.add(pop()); } 

硬币的另一面是pushAll应该像这样定义:

 // Wildcard type for parameter that serves as an E producer public void pushAll(Iterable src) { for (E e : src) push(e); } 

更新: Josh Bloch传播此助记符以帮助您记住要使用的通配符类型:

PECS代表生产者延伸,消费者超级

有关更多详细信息,请参阅Effective Java 2nd Ed。,Item 28 。

这被称为“有界通配符”。 这在官方教程中得到了很好的解释。

如本教程中所述,您因此知道该列表包含恰好一个T子类型的对象

例如List List只能包含Integer s或者只能包含Long s,但不能同时包含两者。

这些事物在类型理论中已知为方差 是一个共变符号, 是一种反变体符号。 最简单的解释是? 可以用共变量表示法中的任何延伸T类型替换,并且? 可以用T在对立变体中延伸的任何类型替换。

使用co和contra-variance比起初看起来要困难得多,特别是因为方差根据位置“切换”。

一个简单的例子是函数类。 假设您有一个带A的函数并返回B 对它的正确表示法是说A是反变体和B os共变体。 为了更好地理解这种情况,让我们考虑一个方法 – 让我们称之为g – 接收这个假设的函数类,其中f应该接收Arc2D并返回一个Shape

g ,这个f被称为传递Arc2D ,返回值用于初始化一个Area (需要一个Shape )。

现在,假设您传递的f接收任何Shape并返回Rectangle2D 。 由于Arc2D也是一个Shape ,因此g不会将Arc2D传递给f ,并且由于Rectangle2D也是一个Shape ,因此它可以传递给Area的构造函数。

如果您尝试反转任何差异或交换该示例中的预期和实际类型,您将看到它失败。 我现在没有时间写下这段代码,而且无论如何我的Java都很生疏,但我会看到我以后能做什么 – 如果没有人能够先做到这一点。

Java Generics FAQ对Javagenerics有很好的解释。 检查问题什么是有界通配符? 它详细解释了构造“?super T”的用法。