文档

Java™ 教程
隐藏目录
通配符使用指南
路径:学习Java语言
课程:泛型(更新)
章节:通配符

通配符使用指南

在学习使用泛型编程时,更令人困惑的是确定何时使用上界通配符和何时使用下界通配符。本页面提供了一些设计代码时应遵循的指南。

在本讨论中,将变量视为提供两种功能之一是有帮助的:

“输入”变量
“输入”变量向代码提供数据。想象一个具有两个参数的复制方法:copy(src, dest)。其中的src参数提供要复制的数据,因此它是“输入”参数。
“输出”变量
“输出”变量保存供其他地方使用的数据。在复制示例中,copy(src, dest)dest参数接受数据,因此它是“输出”参数。

当然,有些变量既用于“输入”又用于“输出” —— 这种情况也在指南中考虑到了。

在决定是否使用通配符以及何种类型的通配符时,可以使用“输入”和“输出”的原则。以下列表提供了遵循的指南:


通配符指南: 
  • 使用上界通配符来定义“输入”变量,使用extends关键字。
  • 使用下界通配符来定义“输出”变量,使用super关键字。
  • 在“输入”变量可以使用在Object类中定义的方法的情况下,使用无界通配符。
  • 在代码需要将变量同时作为“输入”和“输出”变量访问时,不要使用通配符。

这些指南不适用于方法的返回类型。应避免使用通配符作为返回类型,因为这会强制使用代码的程序员处理通配符。

List<? extends ...>定义的列表可以非正式地视为只读,但这不是严格的保证。假设有以下两个类:

class NaturalNumber {

    private int i;

    public NaturalNumber(int i) { this.i = i; }
    // ...
}

class EvenNumber extends NaturalNumber {

    public EvenNumber(int i) { super(i); }
    // ...
}

考虑以下代码:

List<EvenNumber> le = new ArrayList<>();
List<? extends NaturalNumber> ln = le;
ln.add(new NaturalNumber(35));  // 编译时错误

因为List<EvenNumber>List<? extends NaturalNumber>的子类型,可以将le赋给ln。但是,不能使用ln向只包含偶数的列表中添加一个自然数。以下对列表的操作是可能的:

可以看出,由List<? extends NaturalNumber>定义的列表在严格意义上并不是只读的,但是你可以这样认为,因为你无法在列表中存储新元素或更改现有元素。


上一页: 通配符捕获和辅助方法
下一页: 类型擦除