Skip to content

Commit 3960d8f

Browse files
committed
通配符和超类
1 parent a290146 commit 3960d8f

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* [第二章(子类型化和通配符)](ch02/00_Subtyping_and_Wildcards.md#第二章(子类型化和通配符))
2828
* [子类型化和替代原则](ch02/01_Subtyping_and_the_Substitution_Principle.md#子类型化和替代原则)
2929
* [通配符和继承](ch02/02_Wildcards_with_extends.md#通配符和继承)
30-
30+
* [通配符和超类](ch02/03_Wildcards_with_super.md#通配符和超类)
3131
---
3232

3333
![Java Generics and Collections](book.jpg)

SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@
1717
* [断言](ch01/05_Assertions.md#断言)
1818
* [第二章(子类型化和通配符)](ch02/00_Subtyping_and_Wildcards.md#第二章(子类型化和通配符))
1919
* [子类型化和替代原则](ch02/01_Subtyping_and_the_Substitution_Principle.md#子类型化和替代原则)
20-
* [通配符和继承](ch02/02_Wildcards_with_extends.md#通配符和继承)
20+
* [通配符和继承](ch02/02_Wildcards_with_extends.md#通配符和继承)
21+
* [通配符和超类](ch02/03_Wildcards_with_super.md#通配符和超类)

ch02/03_Wildcards_with_super.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
《《《 [返回首页](../README.md)
2+
3+
### 通配符和超类
4+
5+
- 下面是一个方法,它将方便类集合中的源列表中的所有元素复制到目标列表中:
6+
7+
```java
8+
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
9+
for (int i = 0; i < src.size(); i++) {
10+
dst.set(i, src.get(i));
11+
}
12+
}
13+
```
14+
15+
- 这个奇怪的短语`? super T`意味着目的地列表可能有元素任何类型都是`T`的超类型,
16+
就像源列表可能有任何类型的元素是`T`的子类型:
17+
18+
- 这是一个调用示例:
19+
20+
```java
21+
List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
22+
List<Integer> ints = Arrays.asList(5, 6);
23+
Collections.copy(objs, ints);
24+
assert objs.toString().equals("[5, 6, four]");
25+
```
26+
27+
- 与任何泛型方法一样,可以推断或者可以明确给出类型参数。 在这种情况下,
28+
有四种可能的选择,所有这些类型检查和所有这些都具有相同的效果:
29+
30+
```java
31+
Collections.copy(objs, ints);
32+
Collections.<Object>copy(objs, ints);
33+
Collections.<Number>copy(objs, ints);
34+
Collections.<Integer>copy(objs, ints);
35+
```
36+
- 第一次调用离开类型参数隐式; 它被认为是`Integer`,因为这是最有效的选择。
37+
在第三行中,类型参数`T`取为`Number`。 该调用被允许,因为`objs`的类型是`List<Object>`
38+
它是`List<? super Number>`的子类型(因为对象是一个数字的超类型,通配符的要求)和整数有`List<Integer>`
39+
这是`List<? extends Number>`的子类型(因为`Integer``Number`的子类型,
40+
正如扩展通配符所要求的那样)。
41+
42+
- 我们也可以用几个可能的签名来声明这个方法。
43+
44+
```java
45+
public static <T> void copy(List<T> dst, List<T> src)
46+
public static <T> void copy(List<T> dst, List<? extends T> src)
47+
public static <T> void copy(List<? super T> dst, List<T> src)
48+
public static <T> void copy(List<? super T> dst, List<? extends T> src)
49+
```
50+
- 第一种限制性太强,因为只有当目的地和来源具有完全相同的类型时才允许呼叫。
51+
其余三个对于使用隐式类型参数的调用是等效的,但是对于显式类型参数不同。
52+
对于上面的示例调用,第二个签名仅在类型参数为`Object`时起作用,第三个签名仅在类型参数为`Integer`时起作用,
53+
最后一个签名对所有三个类型参数起作用(如我们所见),即`Object``Number``Integer`
54+
在签名中始终使用通配符,因为这样可以实现最广泛的调用。
55+
56+
57+
《《《 [返回首页](../README.md)

0 commit comments

Comments
 (0)