最近在看阿里開發(fā)手冊時看到<? extends T >和<? super T>,以及PECS原則。
記錄一下我的理解。
簡單理解就是
- ? extends T與?super T兩者用于泛型對象的讀取和插入操作:
- ? extends T子類限定,被其修飾的對象只能進(jìn)行讀取操作,不能增刪。
- ? super T超類限定,被其修飾的對象只能進(jìn)行增刪操作,不能讀取。
測試類
class human{}
class man extends human{
private String name;
man(){}
man(String name){this.name = name;}
public String getName(){return name};
}
class xiaoming extends man{
private String name;
xiaoming(String name){
this.name = name;
}
public String getName(String name){
return name;
}
}
測試調(diào)用方法
public void test(){
//超類限定對象 可以添加本身和自己的子類
List<? super man> list = new ArrayList<man>();
list.add(new man("man1"));
list.add(new xiaoming("qwe"));
List<man> manList = new ArrayList<>();
manList.add(new man("asd"));
manList.add(new man("qwe"));
testExtends(manList);
testSuper(manList);
}
子類限定
對于傳入的泛型對象只能查看,不能刪改。被? extends T修飾的泛型對象,不能添加其本身,子類或者父類以及其他任一一種對象。
public void testExtends(List<? extends man> list) {
for(man m : list) {
System.out.println(m.getName());
}
System.out.println(list.get(0).getName());
System.out.println(list.isEmpty());
}
超類限定
對傳入的參數(shù)可以進(jìn)行修改,但是不能查看。例如下面的getName()方法就會爆紅,因為傳來的List<? super man> man List是Object類型,且有? super man T限定,即使加了強制轉(zhuǎn)換(man)也無法識別。
public void testSuper(List<? super man> list){
System.out.println("-----進(jìn)入super-----");
list.add(new man("qwee"));
list.remove(0);
System.out.println((man)list.get(0));
//上面這條語句如果加上.getName()就會報紅
//因為(man)list.get(0)不能被當(dāng)成man類型的對象
}

運行結(jié)果 com.example.postest.post是我的包名
將? extends T 和 ? super T運用到實際中。? extends T 修飾的對象只負(fù)責(zé)讀取,? super T修飾的對象只負(fù)責(zé)插入。就是PECS(Producer Extends, Consumer Super)原則。
接著是官方的標(biāo)準(zhǔn)用法,java.util.collection中的copy方法

copy方法