Java泛型你所不知道的點

程序員小迷 2024-04-24 17:58:54

1.泛型方法可以在任何地方和任何場景中使用,包括普通類和泛型類。

泛型類型參數可以是任何引用類型,包括數組和其他泛型類型。

泛型的類型參數不支持基本類型(需要用包裝類)。

當顯式提供類型參數時,Java 語言不支持省略調用該方法的類或對象,否則會出現這樣錯誤的代碼<String>.callMethod("foo","bar")。

2.限定類型中,只允許有一個類(單繼承導致,可以允許多個接口),而且如果有類,這個類必須是限定列表的第一個。

這種類的限定既可以用在泛型方法上也可以用在泛型類上。

不能使用|子句將泛型參數綁定到任一類型。可使用&綁定到多個類型。

3.運行時類型查詢只適用于原始類型

1)if(restrict instanceOf Restrict<Double>){}//合法

2)if(restrict instanceOf Restrict<T>){}//不合法

3)Restrict<Double> restrictDouble=new Restrict<>();

Restrict<String> restrictString=new Restrict<>();

System.out.println(restrictDouble.getClass()==restrictString.getClass());//合法,返回true

4.你始終可以使用無界通配符 (?)在 instanceof 中指定類型,如下所示:

public boolean isAList(Object obj) {

return obj instanceof List<?>;//合法

}

5.以下代碼是合法的

class Solution<T> {

public boolean isTypeARandomString(T t) {

return t instanceof String; //合法

}

public boolean isTypeInstanceOfAString(String s) {

return s instanceof T; // 不合法

}

}

6.泛型類在靜態上下文中類型變量失效。

不能在靜態域或方法中引用類型變量。但若靜態方法本身是泛型方法,就可以。

7.不能創建參數化類型的數組。

Restrict<Double>[] restrictArray;//合法

Restrict<Double>[] restrictArray=new Restrict<Double>[10];//不合法

8.不能實例化類型變量。

9.不能捕獲泛型類的實例。

10.自定義的泛型類不能extends Exception/Throwable

class Problem<T> extends Exception{}//不合法

但是這樣可以:

public <T extends Throwable> void doWork(T t) throws T{

try{

}catch(Throwable e){

throw t;

}

}

11.泛型類可以繼承或者擴展其他泛型類,比如List和ArrayList.

? extends X

對泛型類來說,如果其中提供了get和set類型參數變量的方法的話,set方法是不允許被調用的,會出現編譯錯誤。

? super X

對泛型類來說,如果其中提供了get和set類型參數變量的方法的話,set方法可以被調用的,且能傳入的參數只能是X或者X的子類。get方法只會返回一個Object類型的值。

12.泛型技術在C#和Java之中的使用方式看似相同,但實現上卻有著根本性的分歧。

C#裏面泛型無論在程序源碼中、編譯後的IL中(Intermediate Language,中間語言,這時候泛型是一個占位符),或是運行期的CLR中,都是切實存在的,List<int>與List<String>就是兩個不同的類型,它們在系統運行期生成,有自己的虛方法表和類型數據,這種實現稱爲類型膨脹,基于這種方法實現的泛型稱爲真實泛型。

Java語言中的泛型則不一樣,它只在程序源碼中存在,在編譯後的字節碼文件中,就已經替換爲原來的原生類型(Raw Type,也稱爲裸類型)了,並且在相應的地方插入了強制轉型代碼,因此,對于運行期的Java語言來說,ArrayList<int>與ArrayList<String>就是同一個類,所以泛型技術實際上是Java語言的一顆語法糖,Java語言中的泛型實現方法稱爲類型擦除,基于這種方法實現的泛型稱爲僞泛型。

另外,從Java字節碼中Signature屬性裏我們還可以得出結論,擦除法所謂的擦除,僅僅是對方法的Code屬性中的字節碼進行擦除,實際上元數據中還是保留了泛型信息,這也是我們能通過反射手段取得參數化類型的根本依據。

微風不燥,陽光正好,你就像風一樣經過這裏,願你停留的片刻溫暖舒心。

我是程序員小迷(致力于C、C++、Java、Kotlin、Android、Shell、JavaScript、TypeScript、Python等編程技術的技巧經驗分享),若作品對您有幫助,請關注、分享、點贊、收藏、在看、喜歡,您的支持是我們爲您提供幫助的最大動力。

歡迎關注。助您在編程路上越走越好!

0 阅读:33

程序員小迷

簡介:致力于Android、C等編程技術的技巧經驗分享