7

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

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

我个人从未见过像上面这样的实例化,尽管有这样的声明

A<? extends B> obj = null;

肯定会举行。我一直在泛型中使用通配符来声明方法参数,所以我可能没有经验。

4

1 回答 1

4

实际上new A<? extends B>()不会编译。自 Java 5 以来,它一直是非法的。

但我猜你原来的例子是这样的new A<X<? extends B>>()。后者在 Java 的最新版本中是合法的。

这个想法是,当实例化一个对象时,类型参数的值可以是任何非通配符类型。? extends B是通配符类型,所以它是不允许的。butX<? extends B>不是通配符类型,尽管它具有通配符类型作为组件。所以你可以说合法地打电话new A<X<? extends B>>()

如果你这样想,这些规则是有道理的。? extends B最终,通配符类型不能是字段或变量的声明类型,这是更基本规则的副产品。如果A定义为

class A<T> {
    T value;
}

那么假设new A<? extends B>().value将是一个声明为 type ? extends B的字段。既然这是非法的,那么实例化也是如此。但是new A<X<? extends B>>()没有那个问题。

于 2012-10-06T16:50:11.003 回答