枚举之间的区别和Enumeration ?
Enumeration 和Enumeration ? 如果是这样,有什么区别?
当你得到其中一个时,你可以做什么没有实际的区别,因为type参数只用在“输出”位置。 另一方面,在你可以作为其中一个使用的方面有很大的不同。
假设您有一个Enumeration
– 您无法将此传递给将Enumeration
作为其参数之一的方法。 您可以将它传递给一个采用Enumeration extends ZipEntry>
的方法Enumeration extends ZipEntry>
Enumeration extends ZipEntry>
。
当你有一个在输入和输出位置使用type参数的类型时更有趣 – List
是最明显的例子。 以下是具有参数变体的方法的三个示例。 在每种情况下,我们都会尝试从列表中获取一个项目,然后添加另一个项目。
// Very strict - only a genuine List will do public void Foo(List list) { T element = list.get(0); // Valid list.add(element); // Valid } // Lax in one way: allows any List that's a List of a type // derived from T. public void Foo(List extends T> list) { T element = list.get(0); // Valid // Invalid - this could be a list of a different type. // We don't want to add an Object to a List list.add(element); } // Lax in the other way: allows any List that's a List of a type // upwards in T's inheritance hierarchy public void Foo(List super T> list) { // Invalid - we could be asking a List
有关详细信息,请阅读:
- generics的Java语言指南
- Javagenerics教程(PDF)
- JavagenericsFAQ – 特别是关于通配符的部分
是的,直接来自其中一个sungenerics教程 :
这里Shape是一个抽象类,有三个子类:Circle,Rectangle和Triangle。
public void draw(List
shape) { for(Shape s: shape) { s.draw(this); } } 值得注意的是,draw()方法只能在Shape列表上调用,并且不能在Circle,Rectangle和Triangle列表中调用。 为了让方法接受任何形状,应该写成如下:
public void draw(List extends Shape> shape) { // rest of the code is the same }
现在你已经离开了,让我想起了我希望我们在C#世界中拥有的东西。
除了提供的链接之外,在这个问题的答案中,关于这个主题的C#和Java有一些很好的链接: 逻辑及其对Collections.Generic和inheritance的应用。
选择的是:
- C#中的逆变和协方差 (代码是C#特有的,理论上因为语法不存在[尚未],但总体上涵盖了很多主题。)
- Javagenerics以及参数的协方差和逆变
- Sun的Javagenerics教程 。