? extends T与? super T
字数统计:
908字
|
阅读时长:
4分钟
2017.06.24
Chen hongen
后端
概览 集合框架的源码经常见到“? extends E”、“? super T”。本篇文章以实例+注释讲讲“有限通配符的参数化类型”的创建、存值以及取值。 这两种都是限定类的取值范围的写法。“? extends T”表示类的允许范围是T及其子类;“? super T”表示类的允许范围是T及其父类。也就是new的时候受到此约束。
存值:只要能保证存放类是指定类及其子类即可。null不受“? extends/super T”约束。
取值:“? extends T”取得的默认类型为上界T,“? super T”的默认类型为所有类的父类Object。
Demo 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package generic;
import java.util.PriorityQueue;
public class Extend {
public static void main (String[] args) {
PriorityQueue<? extends Parent> pq = new PriorityQueue<Son>();
PriorityQueue<Son> pqs = new PriorityQueue<Son>();
pqs.add(new Son("1" ));
pqs.add(new Son("2" ));
pqs.add(new Son("3" ));
pqs.add(new Son("4" ));
PriorityQueue<? extends Parent> pq1 = pqs;
Son s = (Son) pq1.poll();
Parent p = pq1.poll();
Person pp= pq1.poll();
System.out.println(s.getName());
System.out.println(p.getName());
System.out.println(pp.getName());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package generic;
import java.util.PriorityQueue;
public class Super {
public static void main (String[] args) {
PriorityQueue<? super Parent> pq = new PriorityQueue<Person>();
pq.add(new Son("1" ));
pq.add(new Daughter("2" ));
pq.add(new Parent("3" ));
Daughter d = (Daughter) pq.poll();
Son s = (Son) pq.poll();*/
Parent p = (Parent) pq.poll();
Parent d = (Parent) pq.poll();
Parent s = (Parent) pq.poll();
System.out.println(d.getName());
System.out.println(p.getName());
System.out.println(s.getName());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package generic;
public class Person implements Comparable <Person > {
protected String name;
public Person (String name) {
super ();
this .name = name;
}
public String getName () {
return name;
}
public void setName (String name) {
this .name = name;
}
@Override
public int compareTo (Person o) {
return o.name.compareTo(this .name);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package generic;
public class Parent extends Person {
private String name;
public Parent (String name) {
super (name);
this .name = name;
}
public String getName () {
return name;
}
public void setName (String name) {
this .name = name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package generic;
public class Son extends Parent {
private String name;
public Son (String name) {
super (name);
this .name = name;
}
public String getName () {
return name;
}
public void setName (String name) {
this .name = name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package generic;
public class Daughter extends Parent {
private String name;
public Daughter (String name) {
super (name);
this .name = name;
}
public String getName () {
return name;
}
public void setName (String name) {
this .name = name;
}
}
说点什么 针对以上特性,java中有“PECS(“Producer Extends,Consumer Super”)”的说法。即如果要用参数化类型表示生产者,就使用<? extends T>;如果表示消费者,就使用<? super T>。
更多有意思的内容,欢迎访问笔者小站: rebey.cn
推荐阅读 Java 泛型: 什么是PECS(Producer Extends, Consumer Super) 。