文档

Java™ 教程-Java Tutorials 中文版
通配符和子类型
Trail: Learning the Java Language
Lesson: Generics (Updated)
Section: Wildcards

通配符和子类型

Generics, Inheritance, and Subtypes 中所述,泛型类或接口不相关,仅仅是因为它们的类型之间存在关系。但是,你可以使用通配符在泛型类或接口之间创建关系。

给定以下两个常规(非泛型)类:

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

编写以下代码是合理的:

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

此示例显示常规类的继承遵循此子类型规则:如果 B 继承(extends) A,则 BA 的子类型。此规则不适用于泛型类型:

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

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

该图表显示 List<Number> 和 List<Integer> 的公共父类是未知类型的列表
公共父类是 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 类之间的关系。

diagram showing that List<Integer> is a subtype of both List<? extends Integer> and List<?super Integer>. List<? extends Integer> is a subtype of List<? extends Number> which is a subtype of List<?>. List<Number> is a subtype of List<? super Number> and List>? extends Number>. List<? super Number> is a subtype of List<? super Integer> which is a subtype of List<?>.
几个泛型 List 类声明的层次结构。

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


Previous page: Lower Bounded Wildcards
Next page: Wildcard Capture and Helper Methods