gpt4 book ai didi

java - 使用通配符创建新的通用对象

转载 作者:搜寻专家 更新时间:2023-10-30 21:17:25 24 4
gpt4 key购买 nike

请解释这个通用代码通配符编译时错误:

//no compile time error.
List<? extends Number> x = new ArrayList<>();

//compile time error.
List<? extends Number> x = new ArrayList<? extends Number>();

最佳答案

用通配符实例化泛型类型是无效的语法。类型List<? extends Number>表示 List 某种类型是或扩展Number .创建这种类型的实例没有意义,因为通过实例化您正在创建特定的东西:

new ArrayList<? extends Number>();//compiler:"Wait, what am I creating exactly?" 

带有通配符的泛型类型只对变量和方法参数有意义,因为这允许在分配/传递给它们的内容方面有更大的自由度。

//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");
}
}

请务必牢记使用通配符带来的限制。

List<? extends Number> numList = ...
numList.add(new Integer(3));//compiler:"Nope, cause that might be a List<Double>"

对于您的第一个示例,菱形是 Java 7 中的一项新功能,它允许编译器根据分配给它的变量类型推断新泛型实例的类型。在这种情况下:

List<? extends Number> x = new ArrayList<>();

编译器很可能推断出 new ArrayList<Number>()在这里,但推断出什么并不重要,只要它是对给定变量的有效赋值即可。这就是引入菱形运算符的原因 - 指定新对象的通用类型是多余的,只要一些通用类型就可以使其成为有效的赋值/参数。

只有当您还记得 Java 中的泛型是一种纯粹的编译时语言特性时,这个推理才有意义,因为 type erasure ,并且在运行时没有意义。通配符的存在只是因为这个限制。相比之下,在 C# 中,泛型类型信息在运行时一直存在——而且该语言中不存在泛型通配符。

关于java - 使用通配符创建新的通用对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9147129/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com