? 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)。