Skip to content

Commit 766e1fc

Browse files
authored
Update 06_The_Principle_of_Indecent_Exposure.md
1 parent 0877226 commit 766e1fc

File tree

1 file changed

+41
-43
lines changed

1 file changed

+41
-43
lines changed

Diff for: ch06/06_The_Principle_of_Indecent_Exposure.md

+41-43
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
回想一下,`2.5` 节介绍了为什么需要物化的一个例子:
1010

1111
```java
12-
Integer[] ints = new Integer[] {1};
13-
Number[] nums = ints;
14-
nums[0] = 1.01; // 数组存储异常
15-
int n = ints[0];
12+
Integer[] ints = new Integer[] {1};
13+
Number[] nums = ints;
14+
nums[0] = 1.01; // 数组存储异常
15+
int n = ints[0];
1616
```
1717

1818
这将整数数组赋给一个数组数组,然后尝试将一个 `double` 存储到数组数组中。 该尝试引发数组存储异常,因为该检查与实体类型有关。 这也是一样,因为否则最后
@@ -21,11 +21,10 @@
2121
下面是一个类似的例子,数组数组被数组列表所取代:
2222

2323
```java
24-
List<Integer>[] intLists
25-
= (List<Integer>[])new List[] {Arrays.asList(1)}; // 未经检查的转换
26-
List<? extends Number>[] numLists = intLists;
27-
numLists[0] = Arrays.asList(1.01);
28-
int n = intLists[0].get(0); // 类抛出异常!
24+
List<Integer>[] intLists = (List<Integer>[])new List[] {Arrays.asList(1)}; // 未经检查的转换
25+
List<? extends Number>[] numLists = intLists;
26+
numLists[0] = Arrays.asList(1.01);
27+
int n = intLists[0].get(0); // 类抛出异常!
2928
```
3029

3130
这将整数列表分配给数组列表,然后尝试将双列表存储到数组列表中。 这次尝试的存储不会失败,即使它应该,因为针对被指定类型的检查是不充分的:被指定的信息只
@@ -34,42 +33,41 @@
3433
`6-1`。 避免不可接受类型的数组
3534

3635
```java
37-
DeceptiveLibrary.java:
38-
import java.util.*;
39-
public class DeceptiveLibrary {
40-
public static List<Integer>[] intLists(int size) {
41-
List<Integer>[] intLists =
42-
(List<Integer>[]) new List[size]; // 未经检查的转换
43-
for (int i = 0; i < size; i++)
44-
intLists[i] = Arrays.asList(i+1);
45-
return ints;
46-
}
47-
}
48-
49-
InnocentClient.java:
50-
import java.util.*;
51-
public class InnocentClient {
52-
public static void main(String[] args) {
53-
List<Integer>[] intLists = DeceptiveLibrary.intLists(1);
54-
List<? extends Number>[] numLists = intLists;
55-
numLists[0] = Arrays.asList(1.01);
56-
int i = intLists[0].get(0); // 类抛出异常!
57-
}
58-
}
36+
DeceptiveLibrary.java:
37+
import java.util.*;
38+
public class DeceptiveLibrary {
39+
public static List<Integer>[] intLists(int size) {
40+
List<Integer>[] intLists = (List<Integer>[]) new List[size]; // 未经检查的转换
41+
for (int i = 0; i < size; i++)
42+
intLists[i] = Arrays.asList(i+1);
43+
return ints;
44+
}
45+
}
46+
47+
InnocentClient.java:
48+
import java.util.*;
49+
public class InnocentClient {
50+
public static void main(String[] args) {
51+
List<Integer>[] intLists = DeceptiveLibrary.intLists(1);
52+
List<? extends Number>[] numLists = intLists;
53+
numLists[0] = Arrays.asList(1.01);
54+
int i = intLists[0].get(0); // 类抛出异常!
55+
}
56+
}
5957
```
6058

6159
`6-1` 给出了一个类似的例子,分为两类,以说明设计不佳的图书馆如何为无辜的客户创造问题。 名为 `DeceptiveLibrary` 的第一个类定义了一个静态方法,该
6260
方法返回给定大小的整数列表数组。 由于不允许通用数组的创建,因此使用原始类型 `List` 的组件创建数组,并使用强制类型为组件提供参数化类型
6361
`List<Integer>`。 演员阵容会产生一个未经检查的警告:
6462

6563
```java
66-
%javac -Xlint:unchecked DeceptiveLibrary.java
67-
DeceptiveLibrary.java:5: warning: [unchecked] unchecked cast
68-
found : java.util.List[]
69-
required: java.util.List<java.lang.Integer>[]
70-
(List<Integer>[]) new List[size]; // unchecked cast
71-
^
72-
1 warning
64+
%javac -Xlint:unchecked DeceptiveLibrary.java
65+
DeceptiveLibrary.java:5: warning: [unchecked] unchecked cast
66+
found : java.util.List[]
67+
required: java.util.List<java.lang.Integer>[]
68+
(List<Integer>[]) new List[size]; // unchecked cast
69+
^
70+
1 warning
7371
```
7472

7573
由于该数组确实是一个整数列表数组,因此该数组似乎是合理的,并且您可能认为可以安全地忽略此警告。 正如我们将要看到的,你无视这个警告!
@@ -78,9 +76,9 @@
7876
运行代码会用双精度列表覆盖整数列表。 尝试从整数列表中提取整数会导致通过擦除隐式插入的强制转换失败:
7977

8078
```java
81-
%java InnocentClient
82-
Exception in thread "main" java.lang.ClassCastException: java.lang.Double
83-
at InnocentClient.main(InnocentClient.java:7)
79+
%java InnocentClient
80+
Exception in thread "main" java.lang.ClassCastException: java.lang.Double
81+
at InnocentClient.main(InnocentClient.java:7)
8482
```
8583

8684
如前一节所述,此错误消息可能会令人困惑,因为该行看起来不包含演员表!
@@ -97,8 +95,8 @@
9795
即使在Java泛型的设计者中,也要花费一些时间来理解不雅暴露原则的重要性。例如,反射库中的以下两种方法违反了该原则:
9896

9997
```java
100-
TypeVariable<Class<T>>[] java.lang.Class.getTypeParameters()
101-
TypeVariable<Method>[] java.lang.Reflect.Method.getTypeParameters()
98+
TypeVariable<Class<T>>[] java.lang.Class.getTypeParameters()
99+
TypeVariable<Method>[] java.lang.Reflect.Method.getTypeParameters()
102100
```
103101

104102
遵循前面的模型,创建自己的Innocent Client版本并不难,它会在没有投射的地方抛出类抛出错误,在这种情况下,正式Java库会播放 `DeceptiveLibrary` 的角

0 commit comments

Comments
 (0)