什麼是泛型?
泛型是程序設計語言的一種特性。允許程序員在強類型程序設計語言中編寫 體驗泛型
代碼時定義一些可變部份,那些部份在使用前必須作出指明。各種程序設計語言和其編譯器、運行環境對泛型的支持均不一樣。將類型參數化以達到代碼復用提高軟件開發工作效率的一種數據類型。泛型類是引用類型,是堆對象,主要是引入了類型參數這個概念。
定義:
泛型是Java SE 1.5的新特性,泛型的本質是參數化類型,也就是說所操作的數據類型被指定為一個參數。這種參數類型可以用在類、接口和方法
的創建中,分別稱為泛型類、泛型接口、泛型方法。 Java語言引入泛型的好處是安全簡單。
在Java SE 1.5之前,沒有泛型的情況的下,通過對類型Object的引用來實現參數的“任意化”,“任意化”帶來的缺點是要做顯式的強制類型
轉換,而這種轉換是要求開發者對實際參數類型可以預知的情況下進行的。對於強制類型轉換錯誤的情況,編譯器可能不提示錯誤,在運行的時候
才出現異常,這是一個安全隱患。
回到頂部
泛型的好處:
泛型的好處是在編譯的時候檢查類型安全,並且所有的強制轉換都是自動和隱式的,提高代碼的重用率。
1、泛型的類型參數只能是類類型(包括自定義類),不能是簡單類型。
2、同一種泛型可以對應多個版本(因為參數類型是不確定的),不同版本的泛型類實例是不兼容的。
3、泛型的類型參數可以有多個。
4、泛型的參數類型可以使用extends語句,例如<T extends superclass>。習慣上稱為“有界類型”。
5、泛型的參數類型還可以是通配符類型。例如Class<?> classType = Class.forName("java.lang.String");
注意:
•泛型是 Java 1.5 的新增特性,它以C++模板為參照,本質是參數化類型(Parameterized Type)的應用。
•類型參數只能用來表示引用類型,泛型在Java中要求,泛型傳入的必須是包裝類型,必須是Object類型的,或者是自定義的類,不能傳入基本類型例如 int、double、char 等。,必須要傳包裝類型如Integer不能用來表示基本類型,但是傳遞基本類型不會報錯,因為它們會自動裝箱成對應的包裝類。
/*iG相當於占位符,用來傳遞數據類型,而不是數據的值,稱為類型參數(名字可以自定義,當然更多的時候我們得按照規范來)
*
*/
//自定義泛型類,多個泛型之間可以用逗號隔開如<iG,iT,..>
class MyArrays<iG>{ //類的泛型必須要放在類名的後面
//調換數組的元素的位置
public void rever(iG[] a){
System.out.println(a);
}
}
public class customToolClass {
public static void main(String[] args){
String[] str=new String[10];
Integer[] intArr = new Integer[10];
//不能傳基本數據類型,就算是整形數組,如int[],也要傳int的包裝類Integer
int[] arr = new int[10];
// MyArrays<int> my1 = new MyArray<int>(); //不能是基本數據類型
MyArrays<Integer> my2 = new MyArrays<Integer>(); // 只能是包裝類
//my2.rever(arr); //不能是整形數組
//標准格式是這樣的,兩邊的類型要匹配
MyArrays<String> aa = new MyArrays<String>();
aa.rever(str);
//下面這兩種也是可以的,但是不推薦,這是java為了向下兼容以前的版本設計的
MyArrays<String> cc = new MyArrays();
MyArrays dd = new MyArrays<String>();
//--------------------------------------------------------------
MyArrays<Integer> aa1 = new MyArrays<Integer>();
aa1.rever(intArr);
}
}
與普通類的定義相比,上面的代碼在類名後面多出了 <iG> ,iG 是自定義的標識符,也是參數,用來傳遞數據的類型,而不是數據的值,我們稱之為類型參數。在泛型中,不但數據的值可以通過參數傳遞,數據的類型也可以通過參數傳遞。iG只是數據類型的占位符,運行時會被替換為真正的數據類型。
傳值參數(我們通常所說的參數)由小括號包圍,如 (int x, double y),類型參數(泛型參數)由尖括號包圍,多個參數由逗號分隔,如 <T> 或 <T, E>。注意:這只是個規范,名稱可以自定義的。
類型參數需要在類名後面給出。一旦給出了類型參數,就可以在類中使用了。類型參數必須是一個合法的標識符,習慣上使用單個大寫字母,通常情況下,K 表示鍵,V 表示值,E 表示異常或錯誤,T 表示一般意義上的數據類型。
泛型類在實例化時必須指出具體的類型,也就是向類型參數傳值,格式為:
className variable<dataType1, dataType2> = new className<dataType1, dataType2>();
也可以省略等號右邊的數據類型,但是會產生警告,即:
className variable<dataType1, dataType2> = new className();
因為在使用泛型類時指明了數據類型,賦給其他類型的值會拋出異常,既不需要向下轉型,也沒有潛在的風險,比本文一開始介紹的自動裝箱和向上轉型要更加實用。
測試效果圖: