Enumeration<?之间有区别吗?扩展ZipEntry>和枚举< ZipEntry>?如果是这样,有什么区别?
答案 0 :(得分:16)
当您获得其中之一时,您可以做的事情没有实际差异,因为type参数仅用于“输出”位置。另一方面,你可以使用作为其中之一的方面存在很大差异。
假设您有Enumeration<JarEntry>
- 您无法将此传递给以Enumeration<ZipEntry>
作为其参数之一的方法。您可以将其传递给采用Enumeration<? extends ZipEntry>
的方法。
当你有一个在输入和输出位置使用type参数的类型时更有趣 - List<T>
是最明显的例子。以下是参数变化的三个方法示例。在每种情况下,我们都会尝试从列表中获取一个项目,然后添加另一个项目。
// Very strict - only a genuine List<T> will do
public void Foo(List<T> 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<String>
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<Object> for a String.
T element = list.get(0);
// Valid (assuming we get the element from somewhere)
// the list must accept a new element of type T
list.add(element);
}
有关详细信息,请阅读:
答案 1 :(得分:4)
是的,直接来自其中一个sun generics tutorials:
这里Shape是一个抽象类 三个子类:圆形,矩形, 和三角。
public void draw(List<Shape> shape) { for(Shape s: shape) { s.draw(this); } }
值得注意的是平局() 方法只能在列表上调用 形状并不能在列表上调用 圆形,矩形和三角形的 例。为了有方法 接受任何形状,应该是 写如下:
public void draw(List<? extends Shape> shape) { // rest of the code is the same }
答案 2 :(得分:0)
现在你已经离开了,让我想起了我希望我们在C#世界中拥有的东西。
除了提供的链接之外,在这个问题的答案中,关于这个主题的C#和Java有一些很好的链接:Logic and its application to Collections.Generic and inheritance
选择的是: