【发布时间】:2009-03-06 19:57:07
【问题描述】:
枚举 和 Enumeration
【问题讨论】:
枚举 和 Enumeration
【问题讨论】:
当你拥有其中一个时,你可以做什么并没有实际的区别,因为类型参数只用于“输出”位置。另一方面,您可以将什么用作作为其中之一。
假设你有一个Enumeration<JarEntry> - 你不能把它传递给一个以Enumeration<ZipEntry> 作为参数之一的方法。您可以将它传递给采用Enumeration<? extends ZipEntry> 的方法。
当你有一个在输入和输出位置都使用类型参数的类型时会更有趣——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);
}
更多详情,请阅读:
【讨论】:
是的,直接来自sun generics tutorials 之一:
这里的 Shape 是一个抽象类 三个子类:圆形、矩形、 和三角形。
public void draw(List<Shape> shape) { for(Shape s: shape) { s.draw(this); } }值得注意的是draw() 方法只能在列表上调用 形状,不能在列表中调用 圆形、矩形和三角形的 例子。为了有方法 接受任何形状,它应该是 写法如下:
public void draw(List<? extends Shape> shape) { // rest of the code is the same }
【讨论】:
现在你刚刚离开并让我想起了我希望我们在 C# 世界中已经结束的事情。
除了提供的链接之外,在这个问题的答案中,还有一些关于 C# 和 Java 的与此主题相关的很好的链接:Logic and its application to Collections.Generic and inheritance
其中一个选择是:
【讨论】: