|
23 | 23 | 例如,这里有一个有两种便利方法的类。 一个将整数列表中的每个整数加在一起,另一个将字符串列表中的每个字符串连接在一起:
|
24 | 24 |
|
25 | 25 | ```java
|
26 |
| - class Overloaded { |
27 |
| - public static int sum(List<Integer> ints) { |
28 |
| - int sum = 0; |
29 |
| - for (int i : ints) sum += i; |
30 |
| - return sum; |
31 |
| - } |
32 |
| - public static String sum(List<String> strings) { |
33 |
| - StringBuffer sum = new StringBuffer(); |
34 |
| - for (String s : strings) sum.append(s); |
35 |
| - return sum.toString(); |
36 |
| - } |
| 26 | +class Overloaded { |
| 27 | + public static int sum(List<Integer> ints) { |
| 28 | + int sum = 0; |
| 29 | + for (int i : ints) |
| 30 | + sum += i; |
| 31 | + return sum; |
37 | 32 | }
|
| 33 | + public static String sum(List<String> strings) { |
| 34 | + StringBuffer sum = new StringBuffer(); |
| 35 | + for (String s : strings) |
| 36 | + sum.append(s); |
| 37 | + return sum.toString(); |
| 38 | + } |
| 39 | +} |
38 | 40 | ```
|
39 | 41 |
|
40 | 42 | 这按预期工作:
|
41 | 43 |
|
42 | 44 | ```java
|
43 |
| - assert sum(Arrays.asList(1,2,3)) == 6; |
44 |
| - assert sum(Arrays.asList("a","b")).equals("ab"); |
| 45 | +assert sum(Arrays.asList(1,2,3)) == 6; |
| 46 | +assert sum(Arrays.asList("a","b")).equals("ab"); |
45 | 47 | ```
|
46 | 48 |
|
47 | 49 | 以下是两种方法签名的删除:
|
48 | 50 |
|
49 | 51 | ```java
|
50 |
| - int sum(List) |
51 |
| - String sum(List) |
| 52 | +int sum(List) |
| 53 | +String sum(List) |
52 | 54 | ```
|
53 | 55 |
|
54 | 56 | 这两种方法有不同的返回类型,这足以让 `Java` 区分它们。
|
55 | 57 |
|
56 | 58 | 但是,假设我们改变了方法,以便每个方法都将其结果附加到参数列表的末尾,而不是返回一个值:
|
57 | 59 |
|
58 | 60 | ```java
|
59 |
| - class Overloaded2 { |
60 |
| - // 编译时错误,不能重载两个擦除相同的方法 |
61 |
| - public static boolean allZero(List<Integer> ints) { |
62 |
| - for (int i : ints) if (i != 0) return false; |
63 |
| - return true; |
64 |
| - } |
65 |
| - public static boolean allZero(List<String> strings) { |
66 |
| - for (String s : strings) if (s.length() != 0) return false; |
67 |
| - return true; |
68 |
| - } |
69 |
| - } |
| 61 | +class Overloaded2 { |
| 62 | + // 编译时错误,不能重载两个擦除相同的方法 |
| 63 | + public static boolean allZero(List<Integer> ints) { |
| 64 | + for (int i : ints) if (i != 0) return false; |
| 65 | + return true; |
| 66 | + } |
| 67 | + public static boolean allZero(List<String> strings) { |
| 68 | + for (String s : strings) if (s.length() != 0) |
| 69 | + return false; |
| 70 | + return true; |
| 71 | + } |
| 72 | +} |
70 | 73 | ```
|
71 | 74 |
|
72 | 75 | 我们打算让这个代码工作如下:
|
73 | 76 |
|
74 | 77 | ```java
|
75 |
| - assert allZero(Arrays.asList(0,0,0)); |
76 |
| - assert allZero(Arrays.asList("","","")); |
| 78 | +assert allZero(Arrays.asList(0,0,0)); |
| 79 | +assert allZero(Arrays.asList("","","")); |
77 | 80 | ```
|
78 | 81 |
|
79 | 82 | 但是,在这种情况下,两种方法的签名的删除是相同的:
|
80 | 83 |
|
81 | 84 | ```java
|
82 |
| - boolean allZero(List) |
| 85 | +boolean allZero(List) |
83 | 86 | ```
|
84 | 87 |
|
85 | 88 | 因此,编译时会报告名称冲突。 不可能给两个方法使用相同的名称,并尝试通过重载来区分它们,因为在擦除之后不可能区分一个方法调用和另一个方法调用。
|
86 | 89 |
|
87 | 90 | 再举一个例子,这里是整数类的一个不好的版本,它试图使一个整数与一个整数或一个长整数进行比较:
|
88 | 91 |
|
89 | 92 | ```java
|
90 |
| - class Integer implements Comparable<Integer>, Comparable<Long> { |
91 |
| - // 编译时错误,不能实现两个擦除相同的接口 |
92 |
| - private final int value; |
93 |
| - public Integer(int value) { this.value = value; } |
94 |
| - public int compareTo(Integer i) { |
95 |
| - return (value < i.value) ? -1 : (value == i.value) ? 0 : 1; |
96 |
| - } |
97 |
| - public int compareTo(Long l) { |
98 |
| - return (value < l.value) ? -1 : (value == l.value) ? 0 : 1; |
99 |
| - } |
100 |
| - } |
| 93 | +class Integer implements Comparable<Integer>, Comparable<Long> { |
| 94 | + // 编译时错误,不能实现两个擦除相同的接口 |
| 95 | + private final int value; |
| 96 | + public Integer(int value) { |
| 97 | + this.value = value; |
| 98 | + } |
| 99 | + public int compareTo(Integer i) { |
| 100 | + return (value < i.value) ? -1 : (value == i.value) ? 0 : 1; |
| 101 | + } |
| 102 | + public int compareTo(Long l) { |
| 103 | + return (value < l.value) ? -1 : (value == l.value) ? 0 : 1; |
| 104 | + } |
| 105 | +} |
101 | 106 | ```
|
102 | 107 |
|
103 | 108 | 如果这得到支持,通常需要对桥接方法进行复杂而混乱的定义(参见第 `3.7` 节)。 到目前为止,最简单和最容易理解的选择是禁止这种情况。
|
|
0 commit comments