泛型中的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<?
extends
Number>
foo3 =
new
ArrayList<?
extends
Number>();
List<?
extends
Number>
foo3 =
new
ArrayList<?
extends
Integer>();
List<?
extends
Number>
foo3 =
new
ArrayList<?
extends
Double>();
- 讀取操作通過以上給定的賦值語句,你一定能從foo3列表中讀取到的元素的型別是什麼呢?你可以讀取到Number,因為以上的列表要麼包含Number元素,要麼包含Number的類元素。
你不能保證讀取到Integer,因為foo3可能指向的是List<Double>。
你不能保證讀取到Double,因為foo3可能指向的是List<Integer>。
- 寫入操作過以上給定的賦值語句,你能把一個什麼型別的元素合法地插入到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<?
super
Integer>
foo3 =
new
ArrayList<Integer>();
List<?
super
Integer>
foo3 =
new
ArrayList<Number>();
List<?
super
Integer>
foo3 =
new
ArrayList<Object>();
- 讀取操作通過以上給定的賦值語句,你一定能從foo3列表中讀取到的元素的型別是什麼呢?你不能保證讀取到Integer,因為foo3可能指向List<Number>或者List<Object>。
你不能保證讀取到Number,因為foo3可能指向List<Object>。
唯一可以保證的是,你可以讀取到Object或者Object子類的物件(你並不知道具體的子類是什麼)。
- 寫入操作通過以上給定的賦值語句,你能把一個什麼型別的元素合法地插入到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的子類物件。
*/
}
相關推薦
Java泛型中extends和super的區別?
<? extends T>和<? super T>是Java泛型中的“萬用字元(Wildcards)”和“邊界(Bounds)”的概念。<? extends T>:是指 “上界萬用字元(Upper Bounds Wildcards)”<
java泛型中extends 和 super的區別
一般對反省中extends 和 super 的區別是這樣介紹的: 關鍵字說明 ? 萬用字元型別<? extends T> 表示型別的上界,表示引數化型別的可能是T 或是 T的子類<? super T> 表示型別下界(Java Core中叫超型別限
泛型中extends和super的區別
首先來說:< ? extends T > 叫 上界萬用字元 < ? super T >叫 下界萬用字元 1. 下面用程式碼來說明上界萬用字元的一些特點 public class Fruit
泛型中extends和super差別
<? extends T>和<? super T>含有JAVA5.0的新的概念。由於它們的外表導致了很多人誤解了它們的用途: 1.<? extends T>首先你很容易誤解它為繼承於T的所有類的集合,這是大錯特錯的,相信能看下去你一定見
java 泛型中 T 和 問號(萬用字元)的區別
型別本來有:簡單型別和複雜型別,引入泛型後把複雜型別分的更細了; 現在List<Object>, List<String>是兩種不同的型別;且無繼承關係; 泛型的好處如: 開始版本 public void write(Integer
Java泛型中T和問號(萬用字元)的區別
型別本來有:簡單型別和複雜型別,引入泛型後把複雜型別分的更細了. 概述 泛型是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>
泛型中的extends和super的區別
在網上看到如下程式碼,不知道為什麼報錯,程式碼如下: public class GenericTest { public static void main(String[] arg
在java的泛型中super和extends的區別
環境 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開發之深入理解泛型extends和super的區別
我想 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