mirror of
https://github.com/sjsdfg/effective-java-3rd-chinese.git
synced 2024-12-27 13:20:21 +08:00
更新第 26 条翻译
This commit is contained in:
parent
792a89d6a2
commit
85836c052b
@ -123,11 +123,11 @@ converted to CAP#1
|
||||
CAP#1 extends Object from capture of ?
|
||||
```
|
||||
|
||||
不可否认的是,这个错误信息留下了一些需要的东西,但是编译器已经完成了它的工作,不管它的元素类型是什么,都不会破坏集合的类型不变性。 你不仅可以将任何元素(除 `null` 以外)放入一个 `Collection<?>` 中,但是不能保证你所得到的对象的类型。 如果这些限制是不可接受的,可以使用泛型方法(详见第 30 条)或有限制配符类型(详见第 31 条)。
|
||||
不可否认的是,这个错误信息留下了一些需要的东西,但是编译器已经完成了它的工作,不管它的元素类型是什么,都不会破坏集合的类型不变性。 你不仅不能将任何元素(除 `null` 以外)放入一个 `Collection<?>` 中,并且根本无法猜测你会得到那种类型的对象。 如果这些限制是不可接受的,可以使用泛型方法(详见第 30 条)或有限制的通配符类型(详见第 31 条)。
|
||||
|
||||
对于不应该使用原始类型的规则,有一些小例外。 **你必须在类字面值(class literals)中使用原始类型。** 规范中不允许使用参数化类型(尽管它允许数组类型和基本类型)[JLS,15.8.2]。 换句话说,`List.class`,`String[].class` 和 `int.class` 都是合法的,但 `List<String>.class` 和 `List<?>.class` 不是合法的。
|
||||
对于不应该使用原始类型的规则,有一些小例外。 **你必须在类字面值(class literals)中使用原始类型。** 规范中不允许使用参数化类型(尽管它允许数组类型和基本类型)[JLS,15.8.2]。 换句话说,`List.class`,`String[].class` 和 `int.class` 都是合法的,但 `List<String>.class` 和 `List<?>.class` 都是不合法的。
|
||||
|
||||
规则的第二个例外涉及 `instanceof` 操作符。 因为泛型类型信息在运行时被删除,所以在无限制通配符类型以外的参数化类型上使用 `instanceof` 运算符是非法的。 使用无限制通配符类型代替原始类型不会以任何方式影响 `instanceof` 运算符的行为。 在这种情况下,尖括号和问号就显得多余。 **以下是使用泛型类型的 `instanceof` 运算符的首选方法:**
|
||||
规则的第二个例外与 `instanceof` 操作符有关。 因为泛型类型信息在运行时被擦除,所以在无限制通配符类型以外的参数化类型上使用 `instanceof` 运算符是非法的。 使用无限制通配符类型代替原始类型,不会对 `instanceof` 运算符的行为产生任何影响。 在这种情况下,尖括号(<>)和问号(?)就显得多余。 **以下是使用泛型类型的 `instanceof` 运算符的首选方法:**
|
||||
|
||||
```java
|
||||
// Legitimate use of raw type - instanceof operator
|
||||
@ -137,9 +137,9 @@ if (o instanceof Set) { // Raw type
|
||||
}
|
||||
```
|
||||
|
||||
请注意,一旦确定 `o` 对象是一个 `Set`,则必须将其转换为通配符 `Set<?>`,而不是原始类型 `Set`。 这是一个强制转换,所以不会导致编译器警告。
|
||||
请注意,一旦确定 `o` 对象是一个 `Set`,则必须将其转换为通配符 `Set<?>`,而不是原始类型 `Set`。 这是一个受检查的(checked)转换,所以不会导致编译器警告。
|
||||
|
||||
总之,使用原始类型可能导致运行时异常,所以不要使用它们。 它们仅用于与泛型引入之前的传统代码的兼容性和互操作性。 作为一个快速回顾,`Set<Object>` 是一个参数化类型,表示一个可以包含任何类型对象的集合,`Set<?>` 是一个通配符类型,表示一个只能包含某些未知类型对象的集合,`Set` 是一个原始类型,它不在泛型类型系统之列。 前两个类型是安全的,最后一个不是。
|
||||
总之,使用原始类型可能导致运行时异常,所以不要使用它们。 原始类型只是为了与引入泛型机制之前的遗留代码进行兼容和互用而提供的。 作为一个快速回顾,`Set<Object>` 是一个参数化类型,表示一个可以包含任何类型对象的集合,`Set<?>` 是一个通配符类型,表示一个只能包含某些未知类型对象的集合,`Set` 是一个原始类型,它不在泛型类型系统之列。 前两个类型是安全的,最后一个不是。
|
||||
|
||||
为了快速参考,下表中总结了本条目(以及本章稍后介绍的一些)中介绍的术语:
|
||||
|
||||
@ -147,7 +147,7 @@ if (o instanceof Set) { // Raw type
|
||||
|:--:|:--:|:--:|:--:|
|
||||
|Parameterized type|参数化类型|`List<String>`|条目 26|
|
||||
|Actual type parameter |实际类型参数|`String`|条目 26|
|
||||
|Generic type|泛型类型 |`List<E>`|条目 26|
|
||||
|Generic type|泛型类型 |`List<E>`|条目 26 和 条目 29|
|
||||
|Formal type parameter|形式类型参数 |`E`|条目 26|
|
||||
|Unbounded wildcard type|无限制通配符类型|`List<?>`|条目 26|
|
||||
|Raw type|原始类型|`List`|条目 26|
|
||||
|
Loading…
Reference in New Issue
Block a user