Skip to content

Commit 281797d

Browse files
authored
format code
1 parent af1349c commit 281797d

File tree

1 file changed

+97
-89
lines changed

1 file changed

+97
-89
lines changed

ch06/02_Instance_Tests_and_Casts.md

+97-89
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,22 @@
88
作为一个例子,考虑使用实例测试并以书面形式强制转换。 下面是 `java.lang` 中类 `Integer` 定义的一个片段(从实际源代码稍微简化了一下):
99

1010
```java
11-
public class Integer extends Number {
12-
private final int value;
13-
public Integer(int value) { this.value=value; }
14-
public int intValue() { return value; }
15-
public boolean equals(Object o) {
16-
if (o instanceof Integer) {
17-
return value == ((Integer)o).intValue();
18-
} else return false;
19-
}
20-
...
21-
}
11+
public class Integer extends Number {
12+
private final int value;
13+
public Integer(int value) {
14+
this.value=value;
15+
}
16+
public int intValue() {
17+
return value;
18+
}
19+
public boolean equals(Object o) {
20+
if (o instanceof Integer) {
21+
return value == ((Integer)o).intValue();
22+
} else
23+
return false;
24+
}
25+
...
26+
}
2227
```
2328

2429
`equals` 方法接受 `Object` 类型的参数,检查对象是否为 `Integer` 类的实例,如果是,则将其转换为 `Integer` 并比较两个整数的值。 此代码可用,因为
@@ -27,23 +32,24 @@
2732
现在考虑一下如何在列表上定义相等性,就像 `java.util` 中的 `AbstractList` 类一样。 定义这个的自然但不正确的方式如下:
2833

2934
```java
30-
import java.util.*;
31-
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
32-
public boolean equals(Object o) {
33-
if (o instanceof List<E>) { // compile-time error
34-
Iterator<E> it1 = iterator();
35-
Iterator<E> it2 = ((List<E>)o).iterator(); // unchecked cast
36-
while (it1.hasNext() && it2.hasNext()) {
37-
E e1 = it1.next();
38-
E e2 = it2.next();
39-
if (!(e1 == null ? e2 == null : e1.equals(e2)))
40-
return false;
41-
}
42-
return !it1.hasNext() && !it2.hasNext();
43-
} else return false;
44-
}
45-
...
46-
}
35+
import java.util.*;
36+
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
37+
public boolean equals(Object o) {
38+
if (o instanceof List<E>) { // compile-time error
39+
Iterator<E> it1 = iterator();
40+
Iterator<E> it2 = ((List<E>)o).iterator(); // unchecked cast
41+
while (it1.hasNext() && it2.hasNext()) {
42+
E e1 = it1.next();
43+
E e2 = it2.next();
44+
if (!(e1 == null ? e2 == null : e1.equals(e2)))
45+
return false;
46+
}
47+
return !it1.hasNext() && !it2.hasNext();
48+
} else
49+
return false;
50+
}
51+
...
52+
}
4753
```
4854

4955
同样,`equals` 方法接受 `Object` 类型的参数,检查对象是否为 `List<E>` 类型的实例,如果是,则将其转换为 `List<E>` 并比较两个列表中的相应元素。此代
@@ -56,17 +62,17 @@
5662
编译上面的代码报告了两个问题,一个是实例测试的错误,另一个是未经检查的演员警告:
5763

5864
```java
59-
% javac -Xlint:unchecked AbstractList.java
60-
AbstractList.java:6: illegal generic type for instanceof
61-
if (!(o instanceof List<E>)) return false; // compile-time error
62-
^
63-
AbstractList.java:8: warning: [unchecked] unchecked cast
64-
found : java.lang.Object
65-
required: List<E>
66-
Iterator<E> it2 = ((List<E>)o).iterator(); // unchecked cast
67-
^
68-
1 error
69-
1 warning
65+
% javac -Xlint:unchecked AbstractList.java
66+
AbstractList.java:6: illegal generic type for instanceof
67+
if (!(o instanceof List<E>)) return false; // compile-time error
68+
^
69+
AbstractList.java:8: warning: [unchecked] unchecked cast
70+
found : java.lang.Object
71+
required: List<E>
72+
Iterator<E> it2 = ((List<E>)o).iterator(); // unchecked cast
73+
^
74+
1 error
75+
1 warning
7076
```
7177

7278
实例检查报告错误,因为没有可能的方法来测试给定对象是否属于类型 `List<E>`。 演员报告未经检查的警告; 它将执行转换,但它不能检查列表元素实际上是否为
@@ -75,24 +81,24 @@
7581
为了解决这个问题,我们用可调整类型 `List<?>` 替换了不可保留类型 `List<E>`。 这是一个更正的定义(再次,从实际来源稍微简化):
7682

7783
```java
78-
import java.util.*;
79-
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
80-
public boolean equals(Object o) {
81-
if (o instanceof List<?>) {
82-
Iterator<E> it1 = iterator();
83-
Iterator<?> it2 = ((List<?>)o).iterator();
84-
while (it1.hasNext() && it2.hasNext()) {
85-
E e1 = it1.next();
86-
Object e2 = it2.next();
87-
if (!(e1 == null ? e2 == null : e1.equals(e2)))
88-
return false;
89-
}
90-
return !it1.hasNext() && !it2.hasNext();
91-
} else
92-
return false;
93-
}
94-
...
95-
}
84+
import java.util.*;
85+
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
86+
public boolean equals(Object o) {
87+
if (o instanceof List<?>) {
88+
Iterator<E> it1 = iterator();
89+
Iterator<?> it2 = ((List<?>)o).iterator();
90+
while (it1.hasNext() && it2.hasNext()) {
91+
E e1 = it1.next();
92+
Object e2 = it2.next();
93+
if (!(e1 == null ? e2 == null : e1.equals(e2)))
94+
return false;
95+
}
96+
return !it1.hasNext() && !it2.hasNext();
97+
} else
98+
return false;
99+
}
100+
...
101+
}
96102
```
97103

98104
除了更改实例测试和强制类型外,第二个迭代器的类型也从 `Iterator<E>` 更改为 `Iterator<?>`,第二个元素的类型从 `E` 更改为 `Object`。 代码类型检查,
@@ -110,12 +116,12 @@
110116
例如,以下方法将集合转换为列表:
111117

112118
```java
113-
public static <T> List<T> asList(Collection<T> c) throws InvalidArgumentException {
114-
if (c instanceof List<?>) {
115-
return (List<T>)c;
116-
} else
117-
throw new InvalidArgumentException("Argument not a list");
118-
}
119+
public static <T> List<T> asList(Collection<T> c) throws InvalidArgumentException {
120+
if (c instanceof List<?>) {
121+
return (List<T>)c;
122+
} else
123+
throw new InvalidArgumentException("Argument not a list");
124+
}
119125
```
120126

121127
编译此代码将成功,不会出现错误或警告。 实例测试没有错误,因为 `List<?>` 是可重用的类型。 由于转换源的类型为 `Collection<T>`,转换不会报告警告,并且
@@ -130,25 +136,27 @@
130136
例如,下面是将对象列表提升为字符串列表的代码,如果对象列表仅包含字符串,则会抛出类转换异常:
131137

132138
```java
133-
class Promote {
134-
public static List<String> promote(List<Object> objs) {
135-
for (Object o : objs)
136-
if (!(o instanceof String))
137-
throw new ClassCastException();
138-
return (List<String>)(List<?>)objs; // unchecked cast
139-
}
140-
public static void main(String[] args) {
141-
List<Object> objs1 = Arrays.<Object>asList("one","two");
142-
List<Object> objs2 = Arrays.<Object>asList(1,"two");
143-
List<String> strs1 = promote(objs1);
144-
assert (List<?>)strs1 == (List<?>)objs1;
145-
boolean caught = false;
146-
try {
147-
List<String> strs2 = promote(objs2);
148-
} catch (ClassCastException e) { caught = true; }
149-
assert caught;
150-
}
151-
}
139+
class Promote {
140+
public static List<String> promote(List<Object> objs) {
141+
for (Object o : objs)
142+
if (!(o instanceof String))
143+
throw new ClassCastException();
144+
return (List<String>)(List<?>)objs; // unchecked cast
145+
}
146+
public static void main(String[] args) {
147+
List<Object> objs1 = Arrays.<Object>asList("one","two");
148+
List<Object> objs2 = Arrays.<Object>asList(1,"two");
149+
List<String> strs1 = promote(objs1);
150+
assert (List<?>)strs1 == (List<?>)objs1;
151+
boolean caught = false;
152+
try {
153+
List<String> strs2 = promote(objs2);
154+
} catch (ClassCastException e) {
155+
caught = true;
156+
}
157+
assert caught;
158+
}
159+
}
152160
```
153161

154162
如果任何对象不是字符串,该方法会在对象列表上抛出循环并抛出类抛出异常。 因此,当方法的最后一行到达时,将对象列表转换为字符串列表是安全的。
@@ -157,13 +165,13 @@
157165
类型列表; 这个演员是安全的。 其次,将通配符类型列表转换为字符串列表; 此演员阵容是允许的,但会产生未经检查的警告:
158166

159167
```java
160-
% javac -Xlint:unchecked Promote.java
161-
Promote.java:7: warning: [unchecked] unchecked cast
162-
found : java.util.List
163-
required: java.util.List<java.lang.String>
164-
return (List<String>)(List<?>)objs; // unchecked cast
165-
^
166-
1 warning
168+
% javac -Xlint:unchecked Promote.java
169+
Promote.java:7: warning: [unchecked] unchecked cast
170+
found : java.util.List
171+
required: java.util.List<java.lang.String>
172+
return (List<String>)(List<?>)objs; // unchecked cast
173+
^
174+
1 warning
167175
```
168176

169177
测试代码将该方法应用于两个列表,一个仅包含字符串(因此成功),另一个包含整数(因此引发异常)。在第一个断言中,为了比较对象列表和字符串列表,我们必须

0 commit comments

Comments
 (0)