Skip to content

Commit 2c9a971

Browse files
authored
Update 04_The_Get_and_Put_Principle.md
1 parent 00f7d71 commit 2c9a971

File tree

1 file changed

+73
-73
lines changed

1 file changed

+73
-73
lines changed

ch02/04_The_Get_and_Put_Principle.md

+73-73
Original file line numberDiff line numberDiff line change
@@ -11,86 +11,86 @@
1111
1212
我们已经在复制方法的签名中看到了这个原理:
1313

14-
```java
15-
public static <T> void copy(List<? super T> dest, List<? extends T> src)
16-
```
14+
```java
15+
public static <T> void copy(List<? super T> dest, List<? extends T> src)
16+
```
1717

1818
该方法从源 `src` 中获取值,因此使用扩展通配符声明值,并将值放入目标 `dst` 中,因此使用超级通配符声明值。
1919

2020
无论何时使用迭代器,都会从结构中获取值,因此请使用扩展通配符。 这是一个需要一个数字集合的方法,每个转换为一个双精度求和:
2121

22-
```java
23-
public static double sum(Collection<? extends Number> nums) {
24-
double s = 0.0;
25-
for (Number num : nums){
26-
s += num.doubleValue();
27-
}
28-
return s;
22+
```java
23+
public static double sum(Collection<? extends Number> nums) {
24+
double s = 0.0;
25+
for (Number num : nums){
26+
s += num.doubleValue();
2927
}
30-
```
28+
return s;
29+
}
30+
```
3131

3232
由于这个使用 `extends`,所有以下的调用是合法的:
3333

34-
```java
35-
List<Integer> ints = Arrays.asList(1,2,3);
36-
assert sum(ints) == 6.0;
37-
List<Double> doubles = Arrays.asList(2.78,3.14);
38-
assert sum(doubles) == 5.92;
39-
List<Number> nums = Arrays.<Number>asList(1,2,2.78,3.14);
40-
assert sum(nums) == 8.92;
41-
```
34+
```java
35+
List<Integer> ints = Arrays.asList(1,2,3);
36+
assert sum(ints) == 6.0;
37+
List<Double> doubles = Arrays.asList(2.78,3.14);
38+
assert sum(doubles) == 5.92;
39+
List<Number> nums = Arrays.<Number>asList(1,2,2.78,3.14);
40+
assert sum(nums) == 8.92;
41+
```
4242

4343
如果不使用 `extends`,前两个调用将不合法
4444

4545
每当你使用add方法时,你把值放到一个结构中,所以使用 `super` 通配符。 这是一个采用数字和整数n的集合的方法将从零开始的前n个整数放入集合中:
4646

47-
```java
48-
public static void count(Collection<? super Integer> ints, int n) {
49-
for (int i = 0; i < n; i++) ints.add(i);
50-
}
51-
```
47+
```java
48+
public static void count(Collection<? super Integer> ints, int n) {
49+
for (int i = 0; i < n; i++) ints.add(i);
50+
}
51+
```
5252

5353
由于这使用 `super`,以下所有调用都是合法的:
5454

55-
```java
56-
List<Integer> ints = new ArrayList<Integer>();
57-
count(ints, 5);
58-
assert ints.toString().equals("[0, 1, 2, 3, 4]");
59-
List<Number> nums = new ArrayList<Number>();
60-
count(nums, 5); nums.add(5.0);
61-
assert nums.toString().equals("[0, 1, 2, 3, 4, 5.0]");
62-
List<Object> objs = new ArrayList<Object>();
63-
count(objs, 5); objs.add("five");
64-
assert objs.toString().equals("[0, 1, 2, 3, 4, five]");
65-
```
55+
```java
56+
List<Integer> ints = new ArrayList<Integer>();
57+
count(ints, 5);
58+
assert ints.toString().equals("[0, 1, 2, 3, 4]");
59+
List<Number> nums = new ArrayList<Number>();
60+
count(nums, 5); nums.add(5.0);
61+
assert nums.toString().equals("[0, 1, 2, 3, 4, 5.0]");
62+
List<Object> objs = new ArrayList<Object>();
63+
count(objs, 5); objs.add("five");
64+
assert objs.toString().equals("[0, 1, 2, 3, 4, five]");
65+
```
6666

6767
如果 `super` 不被使用,最后两个调用将是不合法的。无论何时您将值放入并从同一结构中获取值,都不应使用通配符。
6868

69-
```java
70-
public static double sumCount(Collection<Number> nums, int n) {
71-
count(nums, n);
72-
return sum(nums);
73-
}
74-
```
69+
```java
70+
public static double sumCount(Collection<Number> nums, int n) {
71+
count(nums, n);
72+
return sum(nums);
73+
}
74+
```
7575

7676
集合被传递给 `sum``count`,所以它的元素类型都必须继承 `Number`(按总数要求),`Integer` 的超类(按计数要求)。 唯一满足这两个约束的两个类是
7777
`Number``Integer`,我们选择了第一个。 以下是一个调用示例:
7878

79-
```java
80-
List<Number> nums = new ArrayList<Number>();
81-
double sum = sumCount(nums,5);
82-
assert sum == 10;
83-
```
79+
```java
80+
List<Number> nums = new ArrayList<Number>();
81+
double sum = sumCount(nums,5);
82+
assert sum == 10;
83+
```
8484

8585
由于没有通配符,参数必须是 `Number` 的集合。
8686

8787
如果您不喜欢在 `Number``Integer` 之间进行选择,那么您可能会想到,如果 `Java` 允许您使用 `extends``super` 编写通配符,则不需要选择。 例
8888
如,我们可以写下以下内容:
8989

90-
```java
91-
double sumCount(Collection<? extends Number super Integer> coll, int n)
92-
// 这在java里面是非法的
93-
```
90+
```java
91+
double sumCount(Collection<? extends Number super Integer> coll, int n)
92+
// 这在java里面是非法的
93+
```
9494

9595
然后我们可以在一个数字集合或一个整数集合上调用 `sumCount`。 但 `Java` 不允许这样做。 打乱它的唯一原因是简单,可以想象 `Java` 在将来可能会支持这种表
9696
示法。 但是,现在,如果你想同时获取和放置不要使用通配符。
@@ -100,26 +100,26 @@
100100

101101
例如,考虑下面的代码片段,它使用一个用扩展通配符声明的列表:
102102

103-
```java
104-
List<Integer> ints = new ArrayList<Integer>();
105-
ints.add(1);
106-
ints.add(2);
107-
List<? extends Number> nums = ints;
108-
double dbl = sum(nums); // ok
109-
nums.add(3.14); // compile-time error
110-
```
103+
```java
104+
List<Integer> ints = new ArrayList<Integer>();
105+
ints.add(1);
106+
ints.add(2);
107+
List<? extends Number> nums = ints;
108+
double dbl = sum(nums); // ok
109+
nums.add(3.14); // compile-time error
110+
```
111111

112112
调用它求和是好的,因为它从列表中获取值,但调用 `add` 的不是,因为它将一个值放入列表中。 这也是一样,因为否则我们可以添加双整数列表!相反,考虑下面的
113113
代码片段,它使用一个超级通配符声明的列表:
114114

115-
```java
116-
List<Object> objs = new ArrayList<Object>();
117-
objs.add(1);
118-
objs.add("two");
119-
List<? super Integer> ints = objs;
120-
ints.add(3); // ok
121-
double dbl = sum(ints); // 编译报错
122-
```
115+
```java
116+
List<Object> objs = new ArrayList<Object>();
117+
objs.add(1);
118+
objs.add("two");
119+
List<? super Integer> ints = objs;
120+
ints.add(3); // ok
121+
double dbl = sum(ints); // 编译报错
122+
```
123123

124124
现在调用 `add` 是正常的,因为它将一个值放入列表中,但是对 `sum` 的调用不是,因为它从列表中获取值。 这也是一样,因为包含一个字符串的列表的总和是没有
125125
意义的!
@@ -137,13 +137,13 @@
137137

138138
同样,你也不能从使用超级通配符声明的类型中获取任何东西 - 除了 `Object` 类型的值,它是每个引用类型的超类型:
139139

140-
```java
141-
List<Object> objs = Arrays.<Object>asList(1,"two");
142-
List<? super Integer> ints = objs;
143-
String str = "";
144-
for (Object obj : ints) str += obj.toString();
145-
assert str.equals("1two");
146-
```
140+
```java
141+
List<Object> objs = Arrays.<Object>asList(1,"two");
142+
List<? super Integer> ints = objs;
143+
String str = "";
144+
for (Object obj : ints) str += obj.toString();
145+
assert str.equals("1two");
146+
```
147147

148148
你可能会觉得有帮助的想法? 将 `T` 扩展为包含每个类型的一个区间,该区间由下面的 `null` 类型和上面的 `T`(其中 `null` 的类型是每个引用类型的子类型)
149149
限定。 同样,你可能会想到? `super T` 包含每个类型在由 `T` 和由上面的 `Object` 限定的区间中。

0 commit comments

Comments
 (0)