前几天我正在审查别人的代码,我遇到了引起一些担忧的问题。为了简化,我说我有一个通用的A类和一个抽象的B类。是否允许以下实例化,如果是,为什么?
Object obj = new A<? extends B>();
我个人从未见过像上面这样的实例化,虽然声明如
A<? extends B> obj = null;
肯定会坚持下去。我总是在泛型中使用通配符来声明方法参数,所以我可能没有经验。
答案 0 :(得分:4)
实际上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>>()
没有那个问题。