
圖片.png
常用的泛型類型變量
E:元素(Element),多用于java集合框架
K:關(guān)鍵字(Key)
N:數(shù)字(Number)
T:類型(Type)
V:值(Value)
1、泛型可以在代碼編譯期檢測出類型轉(zhuǎn)換異常的問題
2、泛型是不可以被指定為基本數(shù)據(jù)類型的
3、泛型只在編譯期產(chǎn)生約束,編譯結(jié)束會被擦除(在class文件中指定的泛型被擦除),不會被保留到運行時。
4、泛型要使用'?'來指定繼承關(guān)系,不然會產(chǎn)生編譯類型異常的問題。在泛型里使用繼承關(guān)系的類有3種方式:
?是通配符,泛指所有類型(?在聲明帶范性的變量時使用,T在定義范型類或方法時使用)
一般用于定義一個引用變量,這么做的好處是,如下所示,定義一個sup的引用變量,就可以指向多個對象。
List<?> list = new ArrayList<String>();
list = new ArrayList<Integer>();
list = new ArrayList<Long>();
若不用?,用固定的類型的話,則:
List<String> list = new ArrayList<String>();
List<Integer> list2 = new ArrayList<Integer>();
List<Long> list3 = new ArrayList<Long>();
4.1 使用通配符?,讓泛型的類型檢查失去意義(慎用!)
4.2 指定泛型上邊界,? extends E
4.3 指定泛型下邊界,? super T
5、對于泛型接口,可以用具體的類實現(xiàn),也可以用泛型類實現(xiàn)
5.1 GenericInterImpl implements GenericInter<Integer, String>
要在泛型接口菱形符號<>內(nèi)指定具體的泛型類型。
5.2 GenericInterImpl<T, N> implements GenericInter<T, N>
在泛型類<>中的泛型變量要和接口中相同,順序可變。
6、泛型方法可以用在泛型類、泛型接口中,也可以用在普通類,普通接口中
6.1 對于下面代碼中的方法getMember并不是泛型方法,只有使用泛型標(biāo)識符<>進(jìn)行聲明的方法才是泛型方法如test1方法。
6.2 泛型方法的泛型標(biāo)識符<>中使用的泛型類型變量可以與泛型類使用的相同,但是并不受泛型類指定的泛型類型影響,也就是說泛型方法的泛型聲明和使用是獨立于泛型類的,不受其影響,而其他方法里的泛型類型是受制于泛型類指定的。
1、泛型類
初級使用:定義一個泛型類
public class GenericClassExample<T> {
private T member;
public GenericClassExample(T member) {
this.member = member;
}
public T getMember() {
return this.member;
}
public <E> T test1(T arg1, E arg2) {
return arg1;
}
}
進(jìn)階使用:使用一個泛型類
public class GenericDemo {
public static void main(String[] args) {
GenericClassExample<String> stringGenericClassExample = new GenericClassExample<>("str");
GenericClassExample<Integer> integerGenericClassExample = new GenericClassExample<>(12);
handleMessage(integerGenericClassExample);
handleMessage(stringGenericClassExample);//通配符指定的泛型會失去編譯檢測,在運行時該句會異常
handleMessageExtends(integerGenericClassExample);
handleMessageExtends(stringGenericClassExample);//編譯期就會報錯
handleMessageSuper(integerGenericClassExample);
handleMessageSuper(stringGenericClassExample);//編譯期就會報錯
}
public static void handleMessage(GenericClassExample<?> genericClassExample) {
Integer result = 11 + (Integer) genericClassExample.getMember();
System.out.println(result);
}
public static void handleMessageExtends(GenericClassExample<? extends Number> genericClassExample) {
Integer result = 11 + (Integer) genericClassExample.getMember();
System.out.println(result);
}
public static void handleMessageSuper(GenericClassExample<? super Integer> genericClassExample) {
Integer result = 11 + (Integer) genericClassExample.getMember();
System.out.println(result);
}
}
2、泛型類/接口
public class GenericClass<T>{
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
3、泛型方法(菱形符號<T>確定泛型類型作用范圍,寫在類名后,或方法返回值前)
public class GenericMethod1 {
private static int add(int a, int b) {
System.out.println(a + "+" + b + "=" + (a + b));
return a + b;
}
private static <T> T genericAdd(T a, T b) {
System.out.println(a + "+" + b + "="+a+b);
return a;
}
public static void main(String[] args) {
GenericMethod1.add(1, 2);
GenericMethod1.<String>genericAdd("a", "b");
}
}