Wildcards and Subtyping

Generics, Inheritance, and Subtypes已经讨论过,泛型类或者接口之所以是不相关仅因为它们的类型之间存在关系。然而,你可以用通配符去创建泛型类或者接口之间的关系。

以下面两个常规(非泛型)类为例:

class A { /* ... */ }
class B extends A { /* ... */ }

下面的代码也是合理的:

B b = new B();
A a = b;

上面上代码显示了常规类的继承遵循了子类型规则:如果B扩展自A,则类B是类A的子类型。该规则不适用于泛型类型:

List<B> lb = new ArrayList<>();
List<A> la = lb;   // compile-time error

既然IntegerNumber的子类型,那么List <Integer>List <Number>之间的关系是什么呢?

The common parent is List<?>.

虽然IntegerNumber的子类型,但是List<Integer>不是List<Number>的子类型,实际上,这两个类型并没有关联。List<Number>List<Integer>的共同父类是List<?>

为了在这些类之间创建关系,以便代码可以通过List <Integer>的元素访问Number的方法,请使用上界通配符:

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number>  numList = intList;  // OK. List<? extends Integer> is a subtype of List<? extends Number>

因为IntegerNumber的子类型,并且numListNumber对象的列表,所以现在intList(Integer对象的列表)和numList之间存在关系。下图展示了了使用上下界通配符声明的几个List类之间的关系。

Guidelines for Wildcard Use部分提供有更多关使用上界和下界通配符的后果的信息

Last updated

Was this helpful?