Documentation

The Java™ Tutorials
Hide TOC
Guidelines for Wildcard Use通配符使用指南
Trail: Learning the Java Language
Lesson: Generics (Updated)
Section: Wildcards

Guidelines for Wildcard Use通配符使用指南

One of the more confusing aspects when learning to program with generics is determining when to use an upper bounded wildcard and when to use a lower bounded wildcard. 在学习使用泛型编程时,一个更容易混淆的方面是确定何时使用上界通配符以及何时使用下界通配符。This page provides some guidelines to follow when designing your code.本页提供了设计代码时要遵循的一些准则。

For purposes of this discussion, it is helpful to think of variables as providing one of two functions:在本讨论中,将变量视为提供以下两个函数之一是有帮助的:

An "In" Variable“In”变量
An "in" variable serves up data to the code. “in”变量向代码提供数据。Imagine a copy method with two arguments: copy(src, dest). 设想一个具有两个参数的复制方法:copy(src, dest)The src argument provides the data to be copied, so it is the "in" parameter.src参数提供要复制的数据,因此它是“in”参数。
An "Out" Variable一个“Out”变量
An "out" variable holds data for use elsewhere. “out”变量保存数据以供其他地方使用。In the copy example, copy(src, dest), the dest argument accepts data, so it is the "out" parameter.在复制示例copy(src, dest)中,dest参数接受数据,因此它是“out”参数。

Of course, some variables are used both for "in" and "out" purposes — this scenario is also addressed in the guidelines.当然,有些变量同时用于“输入”和“输出”目的—指南中也讨论了这种情况。

You can use the "in" and "out" principle when deciding whether to use a wildcard and what type of wildcard is appropriate. 在决定是否使用通配符以及合适的通配符类型时,可以使用“in”和“out”原则。The following list provides the guidelines to follow:以下列表提供了应遵循的准则:


Wildcard Guidelines:通配符准则: 
  • An "in" variable is defined with an upper bounded wildcard, using the extends keyword.“in”变量使用一个上限通配符定义,并使用extends关键字。
  • An "out" variable is defined with a lower bounded wildcard, using the super keyword.“out”变量是使用一个下限通配符定义的,使用super关键字。
  • In the case where the "in" variable can be accessed using methods defined in the Object class, use an unbounded wildcard.如果可以使用Object类中定义的方法访问“In”变量,请使用无界通配符。
  • In the case where the code needs to access the variable as both an "in" and an "out" variable, do not use a wildcard.如果代码需要同时作为“In”和“out”变量访问变量,请不要使用通配符。

These guidelines do not apply to a method's return type. 这些准则不适用于方法的返回类型。Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards.应该避免使用通配符作为返回类型,因为它迫使程序员使用代码来处理通配符。

A list defined by List<? extends ...> can be informally thought of as read-only, but that is not a strict guarantee. List<? extends ...>定义的列表可以非正式地认为是只读的,但这不是严格的保证。Suppose you have the following two classes:假设您有以下两个类:

class NaturalNumber {

    private int i;

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

class EvenNumber extends NaturalNumber {

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

Consider the following code:考虑下面的代码:

List<EvenNumber> le = new ArrayList<>();
List<? extends NaturalNumber> ln = le;
ln.add(new NaturalNumber(35));  // compile-time error

Because List<EvenNumber> is a subtype of List<? extends NaturalNumber>, you can assign le to ln. 因为List<EvenNumber>List<? extends NaturalNumber>的子类,所以你可以将le分配给lnBut you cannot use ln to add a natural number to a list of even numbers. 但不能使用ln将自然数添加到偶数列表中。The following operations on the list are possible:可以在列表上执行以下操作:

You can see that the list defined by List<? extends NaturalNumber> is not read-only in the strictest sense of the word, but you might think of it that way because you cannot store a new element or change an existing element in the list.您可以看到由List<? extends NaturalNumber>定义的列表不是严格意义上的只读,但您可能会这样想,因为您无法在列表中存储新元素或更改现有元素。


Previous page: Wildcard Capture and Helper Methods
Next page: Type Erasure