Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并且可能使用已不再可用的技术。
请参阅Java语言更改以了解Java SE 9及以后版本的更新语言特性的摘要。
请参阅JDK发布说明以获取有关所有JDK版本的新功能、增强功能和已删除或弃用选项的信息。
如泛型、继承和子类型所述,泛型类或接口之间的关系并不仅仅因为它们的类型之间存在关系。然而,你可以使用通配符来创建泛型类或接口之间的关系。
给定以下两个普通(非泛型)类:
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; // 编译错误
鉴于Integer是Number的子类型,List<Integer>和List<Number>之间的关系是什么?
虽然Integer是Number的子类型,但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>是List<? extends Number>的子类型
因为Integer是Number的子类型,numList是Number对象的列表,现在intList(Integer对象的列表)和numList之间存在关系。以下图表显示了声明使用上界和下界通配符的多个List类之间的关系。
通配符使用指南部分有关于使用上界和下界通配符的影响的更多信息。