① java泛型< extends T>和< super T>
泛型中<? extends T>和<? super T> 差別
<? extends T>和<? super T>含有.0的新的概念。由於它們的外表導致了很多人誤解了它們的用途:
1.<?
extends T>首先你很容易誤解它為繼承於T的所有類的集合,這是大錯特錯的,相信能看下去你一定見過或用過List<?
extends T>吧?為什麼我說理解成一個集合是錯呢?如果理解成一個集合那為什麼不用List<T>來表示?所以<?
extends
T>不是一個集合,而是T的某一種子類的意思,記住是一種,單一的一種,問題來了,由於連哪一種都不確定,帶來了不確定性,所以是不可能通過
add()來加入元素。你或許還覺得為什麼add(T)不行?因為<? extends
T>是T的某種子類,能放入子類的容器不一定放入超類,也就是沒可能放入T。
2.<? super T>這里比較容易使用,沒<? extends T>這么多限制,這里的意思是,以T類為下限的某種類,簡單地說就是T類的超類。但為什麼add(T)可以呢?因為能放入某一類的容器一定可以放入其子類,多態的概念。
擦除
也
許泛型最具挑戰性的方面是擦除(erasure),這是 Java
語言中泛型實現的底層技術。擦除意味著編譯器在生成類文件時基本上會拋開參數化類的大量類型信息。編譯器用它的強制類型轉換生成代碼,就像程序員在泛型出
現之前手工所做的一樣。區別在於,編譯器開始已經驗證了大量如果沒有泛型就不會驗證的類型安全約束。
通過擦除實現泛型的含意是很重要的,並
且初看也是混亂的。盡管不能將List<Integer> 賦給List<Number>,因為它們是不同的類型,但是
List<Integer> 和 List<Number> 類型的變數是相同的類!要明白這一點,請評價下面的代碼:
new List<Number>().getClass() == new List<Integer>().getClass()
編譯器只為 List 生成一個類。當生成了 List 的位元組碼時,將很少剩下其類型參數的的跟蹤。
當
生成泛型類的位元組碼時,編譯器用類型參數的擦除替換類型參數。對於無限制類型參數(<V>),它的擦除是
Object。對於上限類型參數(<K extends Comparable<K>>),它的擦除是其上限(在本例中是
Comparable)的擦除。對於具有多個限制的類型參數,使用其最左限制的擦除。
如果檢查生成的位元組碼,您無法說出 List<Integer> 和 List<String> 的代碼之間的區別。類型限制 T 在位元組碼中被 T 的上限所取代,該上限一般是 Object。
多重限制
一個類型參數可以具有多個限制。當您想要約束一個類型參數比如說同時為 Comparable 和 Serializable 時,這將很有用。多重限制的語法是用「與」符號分隔限制:
class C<T extends Comparable<? super T>&Serializable>
通配符類型可以具有單個限制 —— 上限或者下限。一個指定的類型參數可以具有一個或多個上限。具有多重限制的類型參數可以用於訪問它的每個限制的方法和域。
類型形參和類型實參
在
參數化類的定義中,佔位符名稱(比如 Collection<V> 中的 V)叫做類型形參(type
parameter),它們類似於方法定義中的形式參數。在參數化類的變數的聲明中,聲明中指定的類型值叫做類型實參(type
argument),它們類似於方法調用中的實際參數。但是實際中二者一般都通稱為「類型參數」。所以給出定義:
interface Collection<V> { ... }
和聲明:
Collection<String> cs = new HashSet<String>();
那麼,名稱 V(它可用於整個 Collection 介面體內)叫做一個類型形參。在 cs 的聲明中,String 的兩次使用都是類型實參(一次用於 Collection<V>,另一次用於 HashSet<V>)。
關
於何時可以使用類型形參,存在一些限制。大多數時候,可以在能夠使用實際類型定義的任何地方使用類型形參。但是有例外情況。不能使用它們創建對象或數組,
並且不能將它們用於靜態上下文中或者處理異常的上下文中。還不能將它們用作父類型(class Foo<T> extends
T),不能用於 instanceof 表達式中,不能用作類常量。
類似地,關於可以使用哪些類型作為類型實參,也存在一些限制。類型實參
必須是引用類型(不是基本類型)、通配符、類型參數,或者其他參數化類型的實例化。所以您可以定義
List<String>(引用類型)、List<?>(通配符)或者
List<List<?>>(其他參數化類型的實例化)。在帶有類型形參 T 的參數化類型的定義中,您也可以聲明
List<T>(類型形參)。
② java里的泛型和通配符
解釋這樣的,希望可以被採納為答案:
1.先解釋最中間的括弧:某一個對象A繼承了K這個類,某一個對象B繼承V這個類
2. Map.Entry是map中的一個方法,該方法可以返回一個對象的集合,那麼現在得這個集合就是,A,B所組成的集合
3.iterator迭代器類似於for循環,將A,B這個集合迭代出來,取出A,B單獨的對象
希望我的回答你滿意。
③ java泛型通配符super問題
繼承的原則是A IS B B是父類,
B has A A是子類
super是調用父類的構造函數,應放在子類構造器的最上面。
④ 關於java泛型方法設定通配符的下限,求高手看我理解是否正確
你第二種之所以不報錯,是因為方向對了,
1的E不一定能轉換成?
但是2的?一定可一轉換成R
⑤ java中判斷輸入對象類型
你想用什麼都行,但我知道現在java中出現了泛型這一概念,我就用泛型做吧!!希望與你有用。代碼如下:
public class testGeneric
{
public static void main(String[] args)
{
System.out.println(getType(123));
System.out.println(getType("sssss"));
}
public static <T> String getType(T t){
if(t instanceof String){
return "string";
}else if(t instanceof Integer){
return "int";
}else{
return " do not know";
}
}
}
/**
* 方法的泛型,否則的話就得用重載;
* 1、如果只指定了<?>,而沒有extends,則默認是允許Object及其下的任何Java類了。也就是任意類。
2、通配符泛型不單可以向下限制,如<? extends Collection>,還可以向上限制,如<? super Double>
,表示類型只能接受Double及其上層父類類型,如Number、Object類型的實例。
3、泛型類定義可以有多個泛型參數,中間用逗號隔開,還可以定義泛型介面,泛型方法。這些都泛型類中泛型的使用規則類似。
*/
⑥ java泛型與通配符
寫E的是模板
而?是一種實例化,是不確定類型的實例化,直接寫?,等同於? extends Object
boolean
removeAll(Collection<?> c),是說,從自身(ArrayList)中移除,任意類型的集合的所有元素。
比如可以是改數Collection<String>,也可以是其他。友亮
而換成E,就被限定好殲寬了。
原因是ArrayList<E>是個模板類,使用的時候總要實例化,比如實例化為
ArrayList<String> list;
那麼這個removeAll參數的類型也被實例化成Collection<E>,這樣是違背了設計的初衷了。
⑦ java 關於泛型以及通配符的使用
泛型可以用"<T>"代表,任意類型的。
解釋: 「<T>」是泛型的默認值,可以被譽寬飢任意類型所代替,如:
List<String> list = new ArayList<String>();這個就定義了一個String類型的」泛型「集合,那麼T的巧閉類型就是字元串。
List<T> list = new ArayList<T>();
可以賦值給list:list.add("StringBatch");
可以獲取到list的值:list.get(0),結果就是」StringBatch「;
這個時候T的類型也是慶返String。也就是說T是動態的,可以被任意指定類型。