1. 程式人生 > >泛型中的extends和super的區別

泛型中的extends和super的區別

在網上看到如下程式碼,不知道為什麼報錯,程式碼如下:

public class GenericTest {  
  
    public static void main(String[] args) throws Exception {  
  
       List<? super Fruit> f0=new ArrayList<Fruit>();  
       f0.add(new Apple());  
       f0.add(new Fruit());  
       f0.add(new SupApple());  
         
       List<? super Fruit> f1=new ArrayList<Apple>();  
       f1.add(new Apple());  
       f1.add(new Fruit());  
         
       List<? extends Fruit> f2=new ArrayList<Fruit>();  
       f2.add(new Apple());  
       f2.add(new Fruit());   
         
       List<? extends Fruit> f3=new ArrayList<Apple>();  
       f3.add(new Apple());  
       f3.add(new Fruit());  
          
       List<? super Apple> f5=new ArrayList<Fruit>();  
       f5.add(new Apple());  
       f5.add(new SupApple());  
       f5.add(new Fruit());  
    }  
}  
 
class Fruit{  
}  
class Apple extends Fruit{  
}   
class SupApple extends Apple{      
} 

首先說下extends和super的卻別(參考:點選開啟連結):

extends

List<? extends Number> foo3的萬用字元宣告,意味著以下的賦值是合法的:

List<? extendsNumber> foo3 = newArrayList<? extendsNumber>();

List<? extendsNumber> foo3 = newArrayList<? extendsInteger>();

List<? extendsNumber> foo3 = newArrayList<? 

extendsDouble>();

  1. 讀取操作通過以上給定的賦值語句,你一定能從foo3列表中讀取到的元素的型別是什麼呢?你可以讀取到Number,因為以上的列表要麼包含Number元素,要麼包含Number的類元素。

    你不能保證讀取到Integer,因為foo3可能指向的是List<Double>。

    你不能保證讀取到Double,因為foo3可能指向的是List<Integer>。

  2. 寫入操作過以上給定的賦值語句,你能把一個什麼型別的元素合法地插入到foo3中呢?

    你不能插入一個Integer元素,因為foo3可能指向List<Double>。

    你不能插入一個Double元素,因為foo3可能指向List<Integer>。

    你不能插入一個Number元素,因為foo3可能指向List<Integer>。

    你不能往List<? extends T>中插入任何型別的物件,因為你不能保證列表實際指向的型別是什麼,你並不能保證列表中實際儲存什麼型別的物件。唯一可以保證的是,你可以從中讀取到T或者T的子類。

super

現在考慮一下List<? super T>。

List<? super Integer> foo3的萬用字元宣告,意味著以下賦值是合法的:

List<? superInteger> foo3 = newArrayList<Integer>();

List<? superInteger> foo3 = newArrayList<Number>();

List<? superInteger> foo3 = newArrayList<Object>();

  1. 讀取操作通過以上給定的賦值語句,你一定能從foo3列表中讀取到的元素的型別是什麼呢?你不能保證讀取到Integer,因為foo3可能指向List<Number>或者List<Object>。

    你不能保證讀取到Number,因為foo3可能指向List<Object>。

    唯一可以保證的是,你可以讀取到Object或者Object子類的物件(你並不知道具體的子類是什麼)。

  2. 寫入操作通過以上給定的賦值語句,你能把一個什麼型別的元素合法地插入到foo3中呢?你可以插入Integer物件,因為上述宣告的列表都支援Integer。

    你可以插入Integer的子類的物件,因為Integer的子類同時也是Integer,原因同上。

    你不能插入Double物件,因為foo3可能指向ArrayList<Integer>。

    你不能插入Number物件,因為foo3可能指向ArrayList<Integer>。

    你不能插入Object物件,因為foo3可能指向ArrayList<Integer>。

通過網上查詢,最終明白了:

public static void main(String[] args) throws Exception {  
    	//定義正確,使用正確。
		List<? super Fruit> f0 = new ArrayList<Fruit>();
		f0.add(new Apple());
		f0.add(new Fruit());
		f0.add(new SupApple());

		List<? super Fruit> f1 = new ArrayList<Apple>(); // ArrayList泛型中的只能是Fruit或者Object,即Fruit本身或者Fruit的父類型別。
		f1.add(new Apple());
		f1.add(new Fruit());

		//定義正確,使用錯誤。
		List<? extends Fruit> f2 = new ArrayList<Fruit>();
		//添加了Apple,f2有可能指向ArrayList<SupApple>
		f2.add(new Apple());
		//添加了Fruit,f2有可能指向ArrayList<SupApple>/ArrayList<Apple>
		f2.add(new Fruit());

		//定義正確,使用錯誤。
		List<? extends Fruit> f3 = new ArrayList<Apple>();
		//添加了Apple,f3有可能指向ArrayList<SupApple>
		f3.add(new Apple());
		//添加了Apple,f3有可能指向ArrayList<SupApple>/ArrayList<Apple>
		f3.add(new Fruit());

		//只能新增Apple以及Apple的子類
		List<? super Apple> f5 = new ArrayList<Fruit>();
		f5.add(new Apple());
		f5.add(new SupApple());
		f5.add(new Fruit());
		
		/**
		 * 總結:
		 * 		extends,只能讀取,不能寫。
		 * 		super:可以讀取,且只能返回Object型別,或Object的子類物件(但是不能確定具體的子類是什麼)
		 * 			      可以寫,? super Xxx ,只能寫Xxx或Xxx的子類物件。
		 */
		
    }  


相關推薦

Javaextendssuper區別

<? extends T>和<? super T>是Java泛型中的“萬用字元(Wildcards)”和“邊界(Bounds)”的概念。<? extends T>:是指 “上界萬用字元(Upper Bounds Wildcards)”<

javaextends super區別

一般對反省中extends 和 super 的區別是這樣介紹的: 關鍵字說明 ? 萬用字元型別<? extends T> 表示型別的上界,表示引數化型別的可能是T 或是 T的子類<? super T> 表示型別下界(Java Core中叫超型別限

extendssuper區別

首先來說:< ? extends T > 叫 上界萬用字元 < ? super T >叫 下界萬用字元 1. 下面用程式碼來說明上界萬用字元的一些特點 public class Fruit

extendssuper差別

<? extends T>和<? super T>含有JAVA5.0的新的概念。由於它們的外表導致了很多人誤解了它們的用途: 1.<? extends T>首先你很容易誤解它為繼承於T的所有類的集合,這是大錯特錯的,相信能看下去你一定見

java T 問號(萬用字元)的區別

型別本來有:簡單型別和複雜型別,引入泛型後把複雜型別分的更細了; 現在List<Object>, List<String>是兩種不同的型別;且無繼承關係; 泛型的好處如: 開始版本 public void write(Integer

JavaT問號(萬用字元)的區別

型別本來有:簡單型別和複雜型別,引入泛型後把複雜型別分的更細了. 概述 泛型是Java SE 1.5的新特性,泛型的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。這種引數型別可以用在類、介面和方法的建立中,分別稱為泛型類、泛型介面、泛型方法。 Java語

? super T? extends T的區別

原文連結          李璟([email protected]) 經常發現有List<? super T>、Set<? extends T>的宣告,是什麼意思呢?<? super T>表示包括T在內的任何T的父類,<? extends

Java ? super T? extends T的區別

原文連結          李璟([email protected]) 經常發現有List<? super T>、Set<? extends T>的宣告,是什麼意思呢?<? super T>

extendssuper區別

在網上看到如下程式碼,不知道為什麼報錯,程式碼如下: public class GenericTest { public static void main(String[] arg

在java的superextends區別

環境 java:1.7+ 前言 主要講的是<? super T> 和 <? extends T>的區別! 這個是我在打算封裝一段通用程式碼時,發現經常用的<? extends T>,網上搜索時,發現其總是要和<? sup

Java? super T? extends T的區別

來自:併發程式設計網 - ifeve.com 譯者:李璟 連結:http://ifeve.com/difference-between-super-t-and-extends-t-in-java/ 原文:http://stackoverflow.com/quest

Android開發之深入理解extendssuper區別

我想 lis dataset 文檔 cnblogs extend 擦除 選擇 提前 摘要: 什麽是泛型?什麽是擦除邊界?什麽是上界限定或下界限定(子類型限定或超類型限定)?什麽是類型安全?泛型extends關和super關鍵字結合通配符?使用的區別,兩種泛型在實際Andro

java<?><T>區別

類型 父類 定義 ext 方法 oid tor 接收 通配符 public static void printColl(ArrayList<?> al){ Iterator<?> it = al.iterator();

java<?><T>有什麽區別

n) add 簽名 object 表達 類型變量 ring 類型 arr public static void printColl(ArrayList<?> al){ Iterator<?> it = al.iterat

(? extends T? super T)

<? extends T>和<? super T>是泛型中的“萬用字元(Wildcards)”和“邊界(Bounds)”的概念。 <? extends T>:上界萬用字元(Upper Bounds Wildcards) <? super

一句話弄懂Java extends super

之前一直用有道筆記,記錄的東西都是隻要自己看得懂就行了,現在嘗試寫文章,發表一下自己的一點點見解,可能有很多不足之處 廢話不多說,開始正文 <? extends E> 上限萬用字元,用來限制類型的上限 <? super E> 下限萬用字元

[轉]java?T的區別

在程式碼中經常會看到這樣的函式 public static void printColl(ArrayList<?> al){ Iterator<?> it = al.iterator(); while(it.hasNext())

《Effective Java 02》--Collection(? extends E)Collection(? super E)

一, Collection<? extends E> 需求1: 按順序將一系列同種型別的元素全部放到堆疊中 public static void main(String[] args) { FanXing2<Number> fan = new Fa

java generic super/extends (java super/extends)

@SuppressWarnings("unchecked") public V computeIfAbsent(K key, MappingFunction<? super K, ? extends V> mappingFunction)

Java-程式設計-使用萬用字元? extends ? super

泛型中使用萬用字元有兩種形式:子型別限定<? extends xxx>和超型別限定<? super xxx>。 (1)子型別限定 下面的程式碼定義了一個Pair<T>類,以及Employee,Manager和President類。 pub