Skip to content

Commit 0877226

Browse files
authored
Update 05_The_Principle_of_Truth_in_Advertising.md
1 parent a5430e8 commit 0877226

File tree

1 file changed

+73
-72
lines changed

1 file changed

+73
-72
lines changed

Diff for: ch06/05_The_Principle_of_Truth_in_Advertising.md

+73-72
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,39 @@
1010
这里是第二次尝试将集合转换为数组,这次使用未经检查的转换,并添加了测试代码:
1111

1212
```java
13-
import java.util.*;
14-
class Wrong {
15-
public static<T> T[] toArray(Collection<T> c) {
16-
T[] a = (T[])new Object[c.size()]; // 未经检查的转换
17-
int i=0; for (T x : c) a[i++] = x;
18-
return a;
19-
}
20-
public static void main(String[] args) {
21-
List<String> strings = Arrays.asList("one","two");
22-
String[] a = toArray(strings); // 类抛出错误
23-
}
24-
}
13+
import java.util.*;
14+
class Wrong {
15+
public static<T> T[] toArray(Collection<T> c) {
16+
T[] a = (T[])new Object[c.size()]; // 未经检查的转换
17+
int i=0; for (T x : c) a[i++] = x;
18+
return a;
19+
}
20+
public static void main(String[] args) {
21+
List<String> strings = Arrays.asList("one","two");
22+
String[] a = toArray(strings); // 类抛出错误
23+
}
24+
}
2525
```
2626

2727
上一节中的代码使用短语 `new T[c.size()]` 创建数组,导致编译器报告通用数组创建错误。 新代码改为分配一个对象数组并将其转换为 `T []` 类型,这会导致编
2828
译器发出未经检查的强制转换警告:
2929

3030
```java
31-
% javac -Xlint Wrong.java
32-
Wrong.java:4: warning: [unchecked] 未经检查的转换
33-
found : java.lang.Object[]
34-
required: T[]
35-
T[] a = (T[])new Object[c.size()]; // 未经检查的转换
36-
^
37-
1 warning
31+
% javac -Xlint Wrong.java
32+
Wrong.java:4: warning: [unchecked] 未经检查的转换
33+
found : java.lang.Object[]
34+
required: T[]
35+
T[] a = (T[])new Object[c.size()]; // 未经检查的转换
36+
^
37+
1 warning
3838
```
3939

4040
正如你从这个程序选择的名字中猜出的那样,这个警告不应该被忽略。 事实上,运行这个程序给出了以下结果:
4141

4242
```java
43-
% java Wrong
44-
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
45-
at Wrong.main(Wrong.java:11)
43+
% java Wrong
44+
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
45+
at Wrong.main(Wrong.java:11)
4646
```
4747

4848
难懂的短语 `[Ljava.lang.Object` 是数组的指定类型,其中 `[L` 表示它是引用类型的数组,而 `java.lang.Object` 是数组的组件类型。 类转换错误消息引用包
@@ -52,18 +52,18 @@
5252
在调用 `toArray` 时插入相应的强制转换,从而生成以下等效代码:
5353

5454
```java
55-
import java.util.*;
56-
class Wrong {
57-
public static Object[] toArray(Collection c) {
58-
Object[] a = (Object[])new Object[c.size()]; // unchecked cast
59-
int i=0; for (Object x : c) a[i++] = x;
60-
return a;
61-
}
62-
public static void main(String[] args) {
63-
List strings = Arrays.asList(args);
64-
String[] a = (String[])toArray(strings); // class cast error
65-
}
66-
}
55+
import java.util.*;
56+
class Wrong {
57+
public static Object[] toArray(Collection c) {
58+
Object[] a = (Object[])new Object[c.size()]; // unchecked cast
59+
int i=0; for (Object x : c) a[i++] = x;
60+
return a;
61+
}
62+
public static void main(String[] args) {
63+
List strings = Arrays.asList(args);
64+
String[] a = (String[])toArray(strings); // class cast error
65+
}
66+
}
6767
```
6868

6969
类型擦除将未选中的转换转换为 `T []` 转换为 `Object []` 的转换,并在调用 `toArray` 时将转换插入 `String []`。 运行时,这些转换中的第一个成功。 但
@@ -87,25 +87,26 @@
8787
以下是实施替代方案的代码:
8888

8989
```java
90-
import java.util.*;
91-
class Right {
92-
public static <T> T[] Array(toCollection<T> c, T[] a) {
93-
if (a.length< c.size())
94-
a = (T[])java.lang.reflect.Array. // unchecked cast
95-
newInstance(a.get Class().getComponentType(), c.size());
96-
int i=0; for (T x : c) a[i++] = x;
97-
if (i< a.length) a[i] = null;
98-
return a;
99-
}
100-
public static void main(String[] args) {
101-
List<String> strings = Arrays.asList("one", "two");
102-
String[] a = toArray(strings, new String[0]);
103-
assert Arrays.toString(a).equals("[one, two]");
104-
String[] b = new String[] { "x","x","x","x" };
105-
toArray(strings, b);
106-
assert Arrays.toString(b).equals("[one, two, null, x]");
107-
}
108-
}
90+
import java.util.*;
91+
class Right {
92+
public static <T> T[] Array(toCollection<T> c, T[] a) {
93+
if (a.length< c.size())
94+
a = (T[])java.lang.reflect.Array. // unchecked cast
95+
newInstance(a.get Class().getComponentType(), c.size());
96+
int i=0; for (T x : c) a[i++] = x;
97+
if (i< a.length)
98+
a[i] = null;
99+
return a;
100+
}
101+
public static void main(String[] args) {
102+
List<String> strings = Arrays.asList("one", "two");
103+
String[] a = toArray(strings, new String[0]);
104+
assert Arrays.toString(a).equals("[one, two]");
105+
String[] b = new String[] { "x","x","x","x" };
106+
toArray(strings, b);
107+
assert Arrays.toString(b).equals("[one, two, null, x]");
108+
}
109+
}
109110
```
110111

111112
这使用反射库中的三个方法来分配一个与旧数组具有相同组件类型的新数组:方法 `getClass`(在 `java.lang.Object` 中)返回表示数组类型的 `Class` 对象
@@ -127,11 +128,11 @@
127128
集合框架包含两个将集合转换为数组的方法,类似于我们刚刚讨论的那个:
128129

129130
```java
130-
interface Collection<E> {
131-
...
132-
public Object[] toArray();
133-
public <T> T[] toArray(T[] a)
134-
}
131+
interface Collection<E> {
132+
...
133+
public Object[] toArray();
134+
public <T> T[] toArray(T[] a)
135+
}
135136
```
136137

137138
第一个方法返回一个带有指定组件类型 `Object` 的数组,而第二个方法从参数数组中复制指定组件类型,就像上面的静态方法一样。 就像那种方法一样,如果有空间
@@ -153,20 +154,20 @@
153154
需要未经检查的转换。
154155

155156
```java
156-
import java.util.*;
157-
class RightWithClass {
158-
public static <T> T[] toArray(Collection<T> c, Class<T> k) {
159-
T[] a = (T[])java.lang.reflect.Array. // unchecked cast
160-
newInstance(k, c.size());
161-
int i=0; for (T x : c) a[i++] = x;
162-
return a;
163-
}
164-
public static void main(String[] args) {
165-
List<String> strings = Arrays.asList("one", "two");
166-
String[] a = toArray(strings, String.class);
167-
assert Arrays.toString(a).equals("[one, two]");
168-
}
169-
}
157+
import java.util.*;
158+
class RightWithClass {
159+
public static <T> T[] toArray(Collection<T> c, Class<T> k) {
160+
T[] a = (T[])java.lang.reflect.Array. // unchecked cast
161+
newInstance(k, c.size());
162+
int i=0; for (T x : c) a[i++] = x;
163+
return a;
164+
}
165+
public static void main(String[] args) {
166+
List<String> strings = Arrays.asList("one", "two");
167+
String[] a = toArray(strings, String.class);
168+
assert Arrays.toString(a).equals("[one, two]");
169+
}
170+
}
170171
```
171172

172173
转换方法现在传递类标记 `String.class` 而不是字符串数组。

0 commit comments

Comments
 (0)