泛型通配符实例化

时间:2012-10-06 16:21:35

标签: java generics wildcard declaration instantiation

前几天我正在审查别人的代码,我遇到了引起一些担忧的问题。为了简化,我说我有一个通用的A类和一个抽象的B类。是否允许以下​​实例化,如果是,为什么?

Object obj = new A<? extends B>();

我个人从未见过像上面这样的实例化,虽然声明如

A<? extends B> obj = null;
肯定会坚持下去。我总是在泛型中使用通配符来声明方法参数,所以我可能没有经验。

1 个答案:

答案 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>>()没有那个问题。