Java:泛型
阿新 • • 發佈:2022-03-23
泛型
泛型是JDK1.5中加入的新特性,用於解決資料型別的安全性問題。
- 通過在類宣告時通過一個標識表示類中某個屬性的型別或某個方法的返回值及引數型別。
- 保證程式碼執行時不產生 ClassCastException異常
- Java中的泛型只在編譯階段有效****,不進入執行階段
泛型類
- 物件例項化時不指定泛型,預設為Object
- 泛型不同的引用不能相互賦值
/** * 此處的泛型T可以任意取名為A,B,V * 一般使用大寫T, * @param <T> */ class A<T>{ private T key; //此處T為獲取的形參的型別 public void setKey(T key){ this.key = key; } //此處T為返回值的型別 public T getKey(){ return this.key; } }
測試用例:
A<String> a1 = new A<String>();
a1.setKey("泛型類測試");
System.out.println(a1.getKey());
//在不進行泛型設定時,預設為Object
A a2 = new A();
a2.setKey(new Object());
Object a3 = a2.getKey();
泛型介面
- 定義介面時新增泛型
interface IB<T>{
T test(T t);
- 定義實現類
- 未傳入泛型實參時,與泛型類的定義相同
- 宣告類的時候,需在類中宣告泛型的型別
class B1<T> implements IB<T>{ @Override public T test(T t) { return t; } }
- 如果實現介面時指定介面的泛型的具體資料型別
- 這個類實現介面所有方法中都要泛型替換實際的具體資料型別
class B2 implements IB<String>{
@Override
public String test(String s) {
return null;
}
}
- 使用案例
//B1可以指定泛型也可以預設為Object
B1<String> b1 = new B1();
//B2不能指定泛型的型別
B2 b2 = new B2();
泛型方法
-
無返回值方法的泛型
<T>
是對方法類的定義
public <T> void test(T s){ T t = s; }
-
有返回值方法的泛型
<T>
是對方法類的定義,T
是返回值的型別
public <T> T test2(T s){
return s;
}
- 可變長方法的泛型
public <T> void Test3(T... s){
for(T s1 : s){
System.out.println(s1);
}
定義類的泛型
- 在類上定義的泛型的變數,可以在普通(非靜態)方法中呼叫
class C<E>{
//在類上定義的泛型的變數,可以在普通方法中呼叫
private E e;
public <T> void test(T s){
System.out.println(this.e);
T t = s;
}
- 靜態方法不可呼叫類中定義的泛型變數
- 泛型的變數不能靜態化(可能因為型別不確定)
- 只能使用靜態方法自己定義的泛型變數
class C<E>{
private E e;
public static void test4(){
//呼叫e報錯
System.out.println(e);
}
- 泛型方法在呼叫前沒有固定型別
- 在呼叫時,泛型為傳入引數的型別,即確定泛型的型別
C<Object> c = new C<Object>();
c.test("9");
Integer i = c.test2(2);
c.test2(true);
萬用字元
- 在不清楚需要進行泛型的資料型別時,使用
<?>
進行限制
class D{
//test方法需要一個list集合的引數,但不清楚list集合的資料型別
public void test(List<?> list){
}
}
- 限制的萬用字元
-
<? extends Person>
:只允許泛型為Person及Person子類的引用呼叫 -
<? super Person>
:只允許泛型為Person及Person的父類的引用呼叫 -
<? extends Comparable>
:只允許泛型為實現Comparable介面的實現類的引用呼叫
類的定義:
- D -> C -> B - > A
- IAImpl 是介面 IA 的實現類
class A1{}
class B3 extends A1{}
class C1 extends B3{}
class D1 extends C1{}
interface IA{}
class IAImpl implements IA{}
測試方法類:
class D2{
public void test1(List<? extends C1> list){}
public void test2(List<? super C1> list){}
public void test3(List<? extends IA> list){}
}
-
<? extends C1>
:
List<C1> list1 = new ArrayList();
List<D1> list2 = new ArrayList();
List<B3> list3 = new ArrayList();
List<A1> list4 = new ArrayList();
d2.test1(list1);
d2.test1(list2);
//d2.test1(list3); 報錯,B為C的父類
-
<? super C1>
:
d2.test2(list1);
//d2.test2(list2);報錯,D為C的子類
d2.test2(list3);
d2.test2(list4);
<? extends IA>
List<IAImpl> list5 = new ArrayList();
d2.test3(list5);