java泛型程序设计——Varargs 警告+不能实例化类型变量
生活随笔
收集整理的這篇文章主要介紹了
java泛型程序设计——Varargs 警告+不能实例化类型变量
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】README
0.1) 本文描述+源代碼均 轉自 core java volume 1, 旨在理解 java泛型程序設計 的 Varargs 警告+不能實例化類型變量 的知識;
【1】 Varargs 警告
1.1)一個相關問題: 向參數個數可變的方法傳遞一個泛型類型的實例;
- 1.1.1)考慮以下方法, 它的參數個數是可變的:
- 1.1.2)應該記得, 實際上參數ts 是一個數組, 包含所有實參, 考慮以下調用:
- 1.1.3)為了調用上述方法: java 虛擬機必須建立一個 Pair 數組, 這就違反了前面的規則, 不過, 對于這種case , 你只會得到一個警告, 而不是 錯誤;
1.4)可以采用以下兩種方法來抑制這種警告(Methods):(解決方法)
- M1)一種方法是 為 包含 addAll 調用的方法增加 標注
- M2)在java se 7中, 還可以用 @SafeVarargs 直接標注addAll 方法:
- 現在就可以用 泛型類型來調用這個方法了;
Annotation)
- A1)可以使用 @SafeVarargs 標注來消除創建泛型數組的有關限制, 方法如下:
- A2)現在可以調用:
- 這看起來方便, 不過隱藏著危險, 如下代碼:
- 能順利運行而不會出現 ArrayStoreException 異常 (因為數組存儲只會檢查擦除的類型), 但在處理 table[0] 時 你會在別處得到一個異常;
【2】不能實例化類型變量
2.1)不能使用像 new T(…), new T[…] 或 T.class 這樣的表達式中的類型變量。
- 2.1.1)看個荔枝:(下面的 Pair 構造器就是非法的)
- 2.1.2)類型擦除將T 改變成 Object, 而且, 本意肯定不希望調用 new Object()。
- 2.1.3)但是可以通過反射調用 Class.newInstance 方法來構造泛型對象:
- 2.1.4)因為, 表達式 T.class 是不合法的, 必須像下面這樣設計 API 以便可以支配Class 對象:
- 2.1.5)以上方法可以按照下列方式調用:
- Attention) Class 類本身就是泛型, 如, String.class 是一個 class《String》 的實例(事實上, 它是唯一的實例)。 因此, makePair 方法能夠推斷出 pair 的類型;
- 2.1.6) 不能構造一個 泛型數組:
- 類型擦除會讓這個方法永遠構造 Object[2]數組;
2.2)如果數組僅僅是作為一個類的私有實例域, 就可以將這個數組聲明為 Object[], 并且在獲取元素時進行類型轉換。
- 2.2.1)看個荔枝: 如 ArrayLIst 可以這樣實現:
- 2.2.2)實際的實現沒有這么清晰:
- 2.2.3)這里, 強制類型轉換 E[] 是一個假想, 而類型 擦除使其無法察覺;
2.3)由于 minmax方法 返回 T[] 數組, 使得這一技術無法施展, 如果掩蓋這個類型會有運行時錯誤。假設實現代碼:
public static <T extends Comparable> T[] minmax(T...a) {Object[] mm = new Object[2];...reutrn (T[]) mm; }2.4)調用String[] ss = minmax(“tom”, “dick”, “Harry”);
對上述代碼的分析(Analysis):
- A1)編譯時不會有任何警告。 但Object[] 引用賦給 String[] 變量時, 將會發生 ClassCastException 異常;
- A2)在這種case下, 利用反射,調用 Array.newIntance;
- A3)ArrayList 類的toArray方法就沒有這么幸運了。 它需要生成一個 T[] 數組, 但沒有成分類類型。 因此, 有下面兩種不同的形式:
- 第二個方法接收一個數組參數。 如果數組足夠大, 就是用這個數組。 否則, 用result 的成分類型構造一個足夠大的 新數組;
總結
以上是生活随笔為你收集整理的java泛型程序设计——Varargs 警告+不能实例化类型变量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑抽奖软件破解版(电脑版抽奖软件下载)
- 下一篇: java泛型程序设计——泛型类的静态上下