The Java™ Tutorials — Generics :Guidelines for Wildcard Use 通配符使用指南

The Java™ Tutorials — Generics :Guidelines for Wildcard Use 通配符使用指南

原文地址:https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html

关键点

  • “输入”和“输出”变量的定义 
    • 输入:负责添加数据到代码中,类比一个入口
    • 输出:负责接收输入的数据,并将其传到需要的地方,类比一个出口
  • 通配符准则: 
    • 一个“输入”变量是通过有上限通配符定义的,它使用了extends关键字
    • 一个“输出”变量是通过有下限通配符定义的,它使用了super关键字
    • 当“输入”变量可通过Object类中的方法获取时,那就使用一个无限制通配符
    • 当代码需要获取一个兼具“输入”和“输出”功能的变量时,就不要使用通配符了
  • List<? extends XXX>不能插入新的元素(但可以插入null),也不能对已经有元素进行更改,但是可以调用clear()方法删除所有元素,可以将其视之为一种广义上的只读 
    • 译者注:用Eclipse看了一下它的方法,所操纵的元素对象都是null类型的。

全文翻译

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 一个“输入”变量

An “in” variable serves up data to the code. Imagine a copy method with two arguments: copy(src, dest). The src argument provides the data to be copied, so it is the “in” parameter.

一个“输入变量”负责把数据添加到代码中。想象一个复制方法,它具有两个参数:copy(src,dest)。这个src参数提供了将要被拷贝的数据对象,因此它就是那个“输入”变量。

An “Out” Variable 一个“输出”变量

An “out” variable holds data for use elsewhere. In the copy example, copy(src, dest), the dest argument accepts data, so it is the “out” parameter.

一个“输出”变量持有了为别处使用的数据。在上面的那个copy(src,dest)案例中,这个dest变量负责接收数据,因此也就是所谓的“输出”变量。

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. The following list provides the guidelines to follow:

在决定是否使用通配符,以及适用的通配符类型时,你就可以使用“输入”和“输出”准则来帮助你做决定。下面就列出了需要遵循的准则:

Wildcard Guidelines 通配符准则

  • An “in” variable is defined with an upper bounded wildcard, using the extends keyword.
  • An “out” variable is defined with a lower bounded wildcard, using the super keyword.
  • In the case where the “in” variable can be accessed using methods defined in the Object class, use an unbounded wildcard.
  • In the case where the code needs to access the variable as both an “in” and an “out” variable, do not use a wildcard.
  • 一个“输入”变量是通过有上限通配符定义的,它使用了extends关键字
  • 一个“输出”变量是通过有下限通配符定义的,它使用了super关键字
  • 当“输入”变量可通过Object类中的方法获取时,那就使用一个无限制通配符
  • 当代码需要获取一个兼具“输入”和“输出”功能的变量时,就不要使用通配符了

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. Suppose you have the following two classes:

一个被List<? extends ...>定义的列表可被简单的想象为一种只读列表,但是这并非是严格保证的。假设你有下面的两个类:

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. But you cannot use ln to add a natural number to a list of even numbers. The following operations on the list are possible:

  • You can add null.
  • You can invoke clear.
  • You can get the iterator and invoke remove.
  • You can capture the wildcard and write elements that you’ve read from the list.

因为List<EvenNumber>List<? extends NaturalNumber>的子类型,你就可以将le赋值给ln。但是你不能使用ln去把一个自然数添加到偶数列表中去。而下面的列表操作是有效的:

  • 可以插入一个null
  • 可以调用clear()方法
  • 可以获取一个遍历器,并调用remove()方法
  • 可以对通配符进行匹配,并写入已经从list读出的元素

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>定义的列表并不是严格意义上的只读,但你可以这么想,因为你不能在list中存储一个新的元素或者改变一个原有的元素。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值