JavaSE進(jìn)階
12.3 泛型通配符
- 只能用于聲明變量|形參上,一般是形參類型上,表示可以接收任意
- 不能用在
- 1、創(chuàng)建對(duì)象,即new 后面
- 2、聲明泛型類、泛型接口,即class和interface
- 3、聲明泛型方法,即返回值類型前面<>中
1、匹配任意類型的通配符
/* ?* ? ?通配符,類型不確定 ?* 1、用于聲明變量|形參上 ?* 不能用在 ?* 1、創(chuàng)建對(duì)象 ?* 2、聲明泛型類、泛型接口、泛型方法 ?*/ public?class?TestGenericWildcard { public?static?void?main(String[] args) { ArrayList<?> list?= new?ArrayList(); list?= new?ArrayList<String>(); list?= new?ArrayList<Integer>(); list?= new?ArrayList<Object>(); list = Collections.list(new StringTokenizer("this is a test")); //但是此list不能添加任意類型的對(duì)象,除了null list.add(null); // list.add("");//因?yàn)?類似于Object,但不等價(jià)與Object,所以還是類型不確定,所以除了null可以給任意引用類型之外,其他類型對(duì)象都不能隨便賦 Object obj = list.get(0);//可以調(diào)用get()方法并使用其返回值。返回值是一個(gè)未知的類型,但是我們知道,它總是一個(gè)Object System.out.println(obj); test(new?ArrayList<Object>()); test(new?ArrayList<String>()); test(new?ArrayList<Integer>()); //編譯錯(cuò)誤:不能用在創(chuàng)建對(duì)象上,右邊屬于創(chuàng)建集合對(duì)象 // ArrayList<?> list2 = new ArrayList<?>(); } public?static?void?test(ArrayList<?> list){ list.add(null); // list.add(""); } //編譯錯(cuò)誤:不能用在泛型方法聲明上,返回值類型前面<>不能使用? // public static <?> void test(ArrayList<?> list){ // // } } //編譯錯(cuò)誤:不能用在泛型類的聲明上 /*class GenericTypeClass<?>{ }*/ |
2、受限泛型:上限、下限
(1)通配符指定上限
上限extends:使用時(shí)指定的類型必須是繼承某個(gè)類,或者實(shí)現(xiàn)某個(gè)接口,即<= ,如
- ? extends Person
- ? extends Comparable
滿足以下規(guī)則
- List<Fruit> 滿足 List<? extends Fruit>
- List<Apple> 滿足 List<? extends Fruit>
- List<FujiApple> 滿足 List<? extends Fruit>
- List<? extends Apple> 滿足 List<? extends Fruit>
- List<?> 不滿足 List<? extends Fruit> 因?yàn)長(zhǎng)ist<?> 等價(jià)于List<? extends Object>
public?static?void?main(String[] args) { ArrayList<Fruit> list1= new?ArrayList<Fruit>(); test(list1); ArrayList<Apple> list2= new?ArrayList<Apple>(); test(list2); ArrayList<FujiApple> list3= new?ArrayList<FujiApple>(); test(list3); ArrayList<? extends?Fruit> list= new?ArrayList<Fruit>(); test(list); ArrayList<? extends?Apple> list4= new?ArrayList<FujiApple>(); test(list4); ArrayList<? extends?Apple> list5= new?ArrayList<Apple>(); test(list5); //編譯錯(cuò)誤,因?yàn)锳rrayList<?>類似于ArrayList<? extends Object> //而且list6有可能賦值new ArrayList<String>(); //而且list6有可能賦值new ArrayList<Object>(); ArrayList<?> list6?= new?ArrayList(); // test(list6); } public?static?void?test(ArrayList<? extends?Fruit> list){ |
如果使用“? extends ?類型”接收泛型對(duì)象的時(shí)候,則不能設(shè)置被泛型指定的內(nèi)容
public?static?void?test(ArrayList<? extends?Fruit> list){ /* ?* 通通編譯錯(cuò)誤 ?* 只能接收使用,不能修改 ?* 因?yàn)椴恢纋ist最終傳入的到底是什么樣的集合 list.add(new Fruit()); list.add(new Apple()); list.add(new Peach());*/ //此處只能是Fruit或以上,不能是Apple等子類,因?yàn)榭赡軅魅氲氖茿rrayList<Fruit>或ArrayList<Peach> for(Fruit f:list){ System.out.println(f); } //Iterator只能使用Iterator<?>或Iterator<? extends Fruit> Iterator<? extends Fruit> iter = list.iterator(); ??????????// Iterator<Fruit> iter = list.iterator();//編譯錯(cuò)誤,因?yàn)榉盒筒恢С侄鄳B(tài) } |
(2)通配符指定下限
下限super:使用時(shí)指定的類型不能小于操作的類,即>=,如
? super Apple
存在以下規(guī)則:
- ArrayList<Apple> ?滿足 ArrayList<? super Apple>
- ArrayList<Fruit> ?滿足 ArrayList<? super Apple>
- ArrayList<Object> ?滿足 ArrayList<? super Apple>
- ArrayList<? super Apple> 滿足 ArrayList<? super Apple>
- ArrayList<? super Fruit> 滿足 ArrayList<? super Apple>
- ArrayList<?> 不滿足 ArrayList<? super Apple>因?yàn)長(zhǎng)ist<?> 等價(jià)于List<? extends Object>,那么可能ArrayList<String>
- ArrayList<? super FujiApple> 不滿足 ArrayList<? super Apple> 因?yàn)榭赡蹵rrayList< FujiApple>
public?static?void?main(String[] args) { ArrayList<Apple> list1= new?ArrayList<Apple>(); test(list1); ArrayList<Fruit> list2= new?ArrayList<Fruit>(); test(list2); ArrayList<Object> list3= new?ArrayList<Object>(); test(list3); ArrayList<? super?Apple> list4= new?ArrayList<Apple>(); test(list4); ArrayList<? super?Fruit> list5= new?ArrayList<Fruit>(); test(list5); ArrayList<? super?Fruit> list6= new?ArrayList<Object>(); test(list6); //編譯錯(cuò)誤 /* ArrayList<? super FujiApple> list= new ArrayList<FujiApple>(); test(list);*/ // //編譯錯(cuò)誤,因?yàn)镕ujiApple是Apple的子類 // ArrayList<? super Apple> list7= new ArrayList<FujiApple>(); // test(list7); //編譯錯(cuò)誤,因?yàn)锳rrayList<?>類似于ArrayList<? extends Object> //而且list8有可能賦值new ArrayList<String>(); ArrayList<?> list8?= new?ArrayList(); // test(list8); } public?static?void?test(ArrayList<? super?Apple> list){} |
如果使用“? super類型”接收泛型對(duì)象的時(shí)候,則能夠添加數(shù)據(jù),但是不能添加父對(duì)象
public?static?void?test(ArrayList<? super?Apple> list){ /* ?* 通通編譯錯(cuò)誤 ?* 只能接收本類或子類對(duì)象 ?* 因?yàn)椴恢纋ist最終傳入的到底是什么樣的集合,如果傳入的是ArrayList<Apple>,那添加Fruit對(duì)象就有問(wèn)題了*/ list.add(new?FujiApple()); list.add(new?Apple()); // list.add(new Fruit()); //此處只能是Object,不能是Apple,Fruit,因?yàn)榭赡軅魅氲氖茿rrayList<Object> for(Object a:list){ System.out.println(a); } } |