我声明了一个方法,其参数是 Number
的子类型如下所示:
public static void organizeData(java.util.List<? extends Number> c) {
//operation on the list
}
我可以将任何非参数化列表作为参数传递。那么使用通配符 <? extends Number>
有什么意义呢? ?
List newList = new LinkedList<>();
ClassName.organizeData(newList);
为什么我得到类型为 Object
的元素来自 c
?而不是 Number
类型?有没有办法只允许一个类型的子类型作为参数传递,而不是也允许非参数化参数?
最佳答案
你在这里问了三个问题,我会分别回答。顺便说一句,您会发现阅读 Java Generics FAQ - considered by many to be the canonical reference on the subject 很有值(value):
- 那么使用通配符
<? extends Number>
有什么意义呢? ?
参数化参数是Number
的子类时需要使用通配符,比如说,Integer
.例如:
import java.util.LinkedList;
import java.util.List;
public class NumberTest {
public static void main(String... args) {
List<Integer> newList = new LinkedList<Integer>();
organizeData(newList); // This works!
anotherMethod(newList); // Doesn't compile
}
private static void organizeData(List<? extends Number> list) {
}
private static void anotherMethod(List<Number> list) {
}
}
第二个方法调用失败并出现编译错误:
NumberTest.java:9: error: method anotherMethod in class NumberTest cannot be applied to given types;
anotherMethod(newList); // Doesn't compile
^
required: List<Number>
found: List<Integer>
reason: actual argument List<Integer> cannot be converted to List<Number> by method invocation conversion
1 error
- 为什么我得到类型为
Object
的元素来自c
?而不是Number
类型?
你得到 Object
类型的原因在你的第二种情况下是因为 you are using the Raw Type.如果出于这个原因可以避免使用原始类型,则永远不要使用它 - 您将失去编译器类型检查的所有优势。
- 有没有办法只允许一个类型的子类型作为参数传递,而不是也允许非参数化参数?
你无法阻止 Heap Pollution按照您描述的方式,因为有人总是可以转换为 Raw 类型,然后再转换为任何需要的类型。泛型仅在编译时构造,并且 are ultimately erased after compilation.这就是为什么只能通过注释来抑制 Unchecked Type Conversion 警告。
关于java - 在方法参数中使用通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26258197/