拥有其中一种后,您在做什么上没有实际差异,因为type参数仅在“输出”位置使用。另一方面,在您可以 用作 其中一个的方面有很大的不同。
假设您有一个
Enumeration<JarEntry>-您无法将其传递给
Enumeration<ZipEntry>作为其参数之一的方法。您 可以
将其传递给采用方法
Enumeration<? extends ZipEntry>。
当您有一个在输入和输出位置都使用type参数的类型时,这会更有趣-
List<T>这是最明显的例子。这是参数有变化的方法的三个示例。在每种情况下,我们都会尝试从列表中获取一项,然后添加另一项。
// Very strict - only a genuine List<T> will dopublic 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 hierarchypublic 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);}
有关更多详细信息,请阅读:
- Java语言泛型指南
- Java泛型教程(PDF)
- Java泛型常见问题解答 -特别是有关通配符的部分
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)