前几天我在审查别人的代码时,遇到了引起一些关注的一行。为简化起见,假设我有一个通用类 A 和一个抽象类 B。是否允许以下实例化?如果允许,为什么?
Object obj = new A<? extends B>();
我个人从来没有见过像上面这样的实例化,尽管像这样的声明
A<? extends B> obj = null;
肯定会持有。我一直在泛型中使用通配符来声明方法参数,所以我可能没有经验。
最佳答案
实际上 new A<? extends B>()
不编译。自 Java 5 以来,它一直是非法的。
但我猜你的原始示例类似于 new A<X<? extends B>>()
.后者在最新版本的 Java 中是合法的。
这个想法是,当实例化一个对象时,类型参数的值可以是任何非通配符类型。 ? extends B
是通配符类型,所以它是不允许的。但是X<? extends B>
不是通配符类型,尽管它有一个通配符类型作为组件。所以你可以说合法地调用new A<X<? extends B>>()
.
如果你这样想,这些规则是有道理的。最终,它是更基本规则的副产品,通配符类型如 ? extends B
不能是字段或变量的声明类型。如果A
定义为
class A<T> {
T value;
}
然后是假设的new A<? extends B>().value
将是一个字段声明的类型 ? extends B
.由于那是非法的,因此实例化也是如此。但是new A<X<? extends B>>()
没有这个问题。
关于java - 泛型通配符实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12761481/