Skip to content

Commit e8e9c40

Browse files
authored
Update 08_Restrictions_on_Wildcards.md
1 parent 341c53a commit e8e9c40

1 file changed

Lines changed: 38 additions & 39 deletions

File tree

ch02/08_Restrictions_on_Wildcards.md

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,45 @@
55

66
**实例创建**在类实例创建表达式中,如果类型是参数化类型,则没有任何类型参数可能是通配符。 例如,以下是非法的:
77

8-
```java
9-
List<?> list = new ArrayList<?>(); // 编译报错
10-
Map<String, ? extends Number> map =
11-
new HashMap<String, ? extends Number>(); // 编译报错
12-
```
8+
```java
9+
List<?> list = new ArrayList<?>(); // 编译报错
10+
Map<String, ? extends Number> map = new HashMap<String, ? extends Number>(); // 编译报错
11+
```
1312

1413
这通常不是困难。 `Get``Put` 原则告诉我们,如果一个结构体包含通配符,那么我们只应该从中得到值(如果它是一个扩展通配符)或者只将值放入它中(如果它
1514
是一个超级通配符)。 为了使结构有用,我们必须同时做到这两点。 因此,我们通常以精确的类型创建结构,即使我们使用通配符类型将值放入或从结构中获取值,如
1615
下例所示:
1716

18-
```java
19-
List<Number> nums = new ArrayList<Number>();
20-
List<? super Number> sink = nums;
21-
List<? extends Number> source = nums;
22-
for (int i=0; i<10; i++) sink.add(i);
23-
double sum=0; for (Number num : source) sum+=num.doubleValue();
24-
```
17+
```java
18+
List<Number> nums = new ArrayList<Number>();
19+
List<? super Number> sink = nums;
20+
List<? extends Number> source = nums;
21+
for (int i=0; i<10; i++) sink.add(i);
22+
double sum=0; for (Number num : source) sum+=num.doubleValue();
23+
```
2524

2625
这里通配符出现在第二行和第三行,但不在创建列表的第一行。
2726

2827
禁止包含通配符的实例创建中只有顶级参数。 允许嵌套通配符。 因此,以下是合法的:
2928

30-
```java
31-
List<List<?>> lists = new ArrayList<List<?>>();
32-
lists.add(Arrays.asList(1,2,3));
33-
lists.add(Arrays.asList("four","five"));
34-
assert lists.toString().equals("[[1, 2, 3], [four, five]]");
35-
```
29+
```java
30+
List<List<?>> lists = new ArrayList<List<?>>();
31+
lists.add(Arrays.asList(1,2,3));
32+
lists.add(Arrays.asList("four","five"));
33+
assert lists.toString().equals("[[1, 2, 3], [four, five]]");
34+
```
3635
3736
即使列表的列表是以通配符类型创建的,其中的每个单独列表都有一个特定的类型:第一个列表是整数列表,第二个列表是字符串列表。 通配符类型禁止我们将内部列表
3837
中的元素作为 `Object` 以外的任何类型提取,但由于这是 `toString` 使用的类型,因此此代码的类型很好。
3938

4039
记住限制的一种方式是通配符和普通类型之间的关系类似于接口和类通配符之间的关系,接口更普遍,普通类型和类更具体,实例创建需要更具体的信息。 考虑以下三条
4140
陈述:
4241

43-
```java
44-
List<?> list = new ArrayList<Object>(); // ok
45-
List<?> list = new List<Object>() // 编译报错
46-
List<?> list = new ArrayList<?>() // 编译报错
47-
```
42+
```java
43+
List<?> list = new ArrayList<Object>(); // ok
44+
List<?> list = new List<Object>() // 编译报错
45+
List<?> list = new ArrayList<?>() // 编译报错
46+
```
4847

4948
第一个是合法的; 第二个是非法的,因为实例创建表达式需要一个类,而不是一个接口; 第三个是非法的,因为实例创建表达式需要普通类型而不是通配符。
5049

@@ -53,29 +52,29 @@
5352

5453
**泛型方法调用**如果泛型方法调用包含显式类型参数,那么这些类型参数不能是通配符。 例如,假设我们有以下通用方法:
5554

56-
```java
57-
class Lists {
58-
public static <T> List<T> factory() { return new ArrayList<T>(); }
59-
}
60-
```
55+
```java
56+
class Lists {
57+
public static <T> List<T> factory() { return new ArrayList<T>(); }
58+
}
59+
```
6160

6261
您可以选择推断的类型参数,也可以传递一个明确的类型参数。 以下两项都是合法的:
6362

64-
```java
65-
List<?> list = Lists.factory();
66-
List<?> list = Lists.<Object>factory();
67-
```
63+
```java
64+
List<?> list = Lists.factory();
65+
List<?> list = Lists.<Object>factory();
66+
```
6867

6968
如果传递一个显式的类型参数,它不能是通配符:
7069

7170
```java
72-
List<?> list = Lists.<?>factory(); // 编译报错
71+
List<?> list = Lists.<?>factory(); // 编译报错
7372
```
7473

7574
和以前一样,可以使用嵌套通配符:
7675

7776
```java
78-
List<List<?>> = Lists.<List<?>>factory(); // ok
77+
List<List<?>> = Lists.<List<?>>factory(); // ok
7978
```
8079
8180
这种限制的动机与之前的相似。 再次,目前还不清楚是否有必要,但这不太可能成为问题。
@@ -84,20 +83,20 @@
8483
型参数,则这些类型不能是通配符。例如,这个声明是非法的:
8584

8685
```java
87-
class AnyList extends ArrayList<?> {...} // 编译报错
86+
class AnyList extends ArrayList<?> {...} // 编译报错
8887
```
8988

9089
这也是:
9190

9291
```java
93-
class AnotherList implements List<?> {...} // 编译报错
92+
class AnotherList implements List<?> {...} // 编译报错
9493
```
9594

9695
但是,像以前一样,嵌套通配符是允许的:
9796

98-
```java
99-
class NestedList extends ArrayList<List<?>> {...} // ok
100-
```
97+
```java
98+
class NestedList extends ArrayList<List<?>> {...} // ok
99+
```
101100

102101
这种限制的动机与前两种类似。 与以前一样,目前还不清楚是否有必要,但不太可能成为问题。
103102

0 commit comments

Comments
 (0)