Java中泛型的使用(日常總結)
一、什麼是泛型
泛型,即“引數化型別”。就是將型別由原來的具體的型別引數化,類似於方法中的變數引數,此時型別也定義成引數形式(可以稱之為型別形參),然後在使用/呼叫時傳入具體的型別(型別實參)。
例子:
public static void main(String[] args) { List a = new ArrayList<String>(); a.add("hello"); a.add(10); for(int i=0;i<a.size();i++){ String str = (String) a.get(i); System.out.println(str); } }
報錯:Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
arrayList可以存任意的型別,存入一個String和一個Integer,再取出來當String型別使用時就會報強制型別轉換異常。
如果我們把第一行變成
List<String> a = new ArrayList<String>();
a.add(10); 在編譯階段,編譯器發現錯誤。
List<String> a = new ArrayList<>(); List<Integer> b =new ArrayList<>(); Class classA = a.getClass(); Class classB = b.getClass(); System.out.println(classA.equals(classB));
結果為true。在編譯過程中,正確檢驗泛型結果後,會將泛型的相關資訊擦出,並且在物件進入和離開方法的邊界處新增型別檢查和型別轉換的方法。泛型的資訊不會進入執行期。
二、泛型的使用
泛型類:
/** * 1、T可以是任意標識,常用的有以下幾種 * E - Element (在集合中使用,因為集合中存放的是元素) * T - Type(Java 類) * K - Key(鍵) * V - Value(值) * N - Number(數值型別) * ? - 表示不確定的java型別 * S、U、V - 2nd、3rd、4th types * 2、例項化泛型類時,必須指定T的型別 */ public class Person<T> { //T由外部的T指定 private T key; public Person(T key) { this.key = key; } public T getKey() { return key; } @Override public String toString() { return "key=" + key; } }
Person<String> p1 = new Person<>("hello");
Person<Integer> p2 = new Person<>(10);
1、泛型的型別引數只能是引用型別,不能是基本型別。
2、不傳入泛型型別實參的話,在泛型類中使用泛型的方法或成員變數定義的型別可以為任何的型別。
3、不能對確切的泛型型別使用instanceof操作,例如X instanceof Person<Integer>不行。
泛型介面:
public interface Student<T> {
public T fun();
}
public class Demo implements Student<String> {
@Override
public String fun() {
String str = new String("hello");
return str;
}
}
如果未傳入泛型實參時,與泛型類的定義相同,在宣告類的時候,需將泛型的宣告也一起加到類中。
public class Demo<T> implements Student<T>{
}
1、T傳入無數個實參,就形成無數種類型的介面。
2、 在實現類實現泛型介面時,如已將泛型型別傳入實參型別,則所有使用泛型的地方都要替換成傳入的實參型別。
泛型方法:
class X {
public <T> T fun(T t){
return t;
}
};
public class Test{
public static void main(String args[]){
X c = new X(); //例項化X物件
String str = c.fun("hello"); //傳遞字串
Integer i = c.fun(10); //傳遞數字
System.out.println(str); // 通過泛型方法返回泛型型別例項
System.out.println(i); // 通過泛型方法返回泛型型別例項
}
}
1、只有聲明瞭<T>的方法才是泛型方法,泛型類中的使用了泛型的成員方法並不是泛型方法,<T>表明該方法將使用泛型型別T,此時才可以在方法中使用泛型型別T。
2、如果靜態方法要使用泛型的話,必須將靜態方法也定義成泛型方法。靜態方法無法訪問類上定義的泛型。
public class Person<T> {
public <T> void show(T t){ // T 和類上的T不是一個T
}
}
本文是自己學習的一個小總結,未完,待續。。。