Sam*_*msh 11 java generics bounded-wildcard
请解释这个通用代码通配符编译时错误:
//no compile time error.
List<? extends Number> x = new ArrayList<>();
//compile time error.
List<? extends Number> x = new ArrayList<? extends Number>();
Run Code Online (Sandbox Code Playgroud)
Pau*_*ora 25
使用通配符实例化泛型类型是无效的语法.类型List<? extends Number>指List的某种类型的,其是或延伸Number.创建这种类型的实例没有意义,因为在实例化时你要创建特定的东西:
new ArrayList<? extends Number>();//compiler:"Wait, what am I creating exactly?"
Run Code Online (Sandbox Code Playgroud)
具有通配符的泛型类型仅对变量和方法参数有意义,因为这样可以更自由地分配/传递给它们.
//compiler:"Okay, so passing in a List<Integer> or a List<Double> are both fine"
public void eatSomeNumbers(List<? extends Number> numbers) {
for (Number number : numbers) {
System.out.println("om nom " + number + " nom");
}
}
Run Code Online (Sandbox Code Playgroud)
请务必记住使用通配符时出现的限制.
List<? extends Number> numList = ...
numList.add(new Integer(3));//compiler:"Nope, cause that might be a List<Double>"
Run Code Online (Sandbox Code Playgroud)
至于您的第一个示例,菱形是Java 7中的一项新功能,它允许编译器根据分配给它的变量的类型推断新通用实例的类型.在这种情况下:
List<? extends Number> x = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
编译器很可能new ArrayList<Number>()在这里推断,但推断的内容几乎不重要,只要它是对给定变量的有效赋值.这就是引入菱形运算符的原因 - 指定新对象的泛型类型是多余的,因为一些泛型类型会使它成为有效的赋值/参数.
如果您记得Java中的泛型是纯粹的编译时语言特性,因为类型擦除,并且在运行时没有意义,这种推理才有意义.通配符只是因为这种限制而存在.相比之下,在C#泛型类型信息在运行时粘附 - 并且该语言中不存在通用通配符.
| 归档时间: |
|
| 查看次数: |
3260 次 |
| 最近记录: |