泛型(10)-泛型擦除與轉換


在嚴格的泛型代碼中,帶有泛型聲明的類總應該帶着泛型參數,但為了與老的Java代碼保持一致,也允許在使用帶泛型聲明的類時不指定實際的類型,如果沒有這個泛型指定實際類型,此時被稱作raq type(原始類型),默認時聲明該泛型形參
時指定的第一個上限類型.

package com.j1803;


class Apple<T extends Number>{
private T size;

public Apple(T size) {
this.size = size;
}

public T getSize() {
return size;
}

public void setSize(T size) {
this.size = size;
}
public Apple(){

}
}

public class ErasureTest {
public static void main(String[] args) {
Apple<Integer> ig=new Apple<>(45);
//iggetSize()方法返回Integer類型對象
Integer as=ig.getSize();
System.out.println(as);

//ig賦值給Apple變量,丟失尖括號里的類型信息
Apple a=ig;
//a只知道size的類型是Number;
Number nm=a.getSize();
//下面代碼引起編譯錯誤a.getSize():java.lang.Number. ig1:java.lang.Integer
// Integer ig1=a.getSize();
}
}
上面程序定義了一個帶有泛型聲明的類AppLe類,其泛型形參的上限是Number,這個泛型形參用來定義Apple類的size變量.當把帶有泛型信息的對象賦值給一個不帶泛型信息的變量時,編譯器就會丟失原來對象的泛型信息,也就是尖括號
里的信息都會丟失,因為Apple的泛型形參的上限是Number類,所以編譯器依然知道a的getSize()返回的是Number類型,但具體是Number的哪個子類就不清楚了



從邏輯上來看,List<String>是List的子類,如果直接把List對象賦給一個List<String>對象應該會引起編譯錯誤,但實際不會.對泛型而言,可以直接把一個List對象賦給一個List<String>對象,僅僅提示"未經檢查的轉換",
package com.j1803;

import java.util.ArrayList;
import java.util.List;

public class ErasureTest2 {
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
List list1=list;
List<String> ls=list1;
//運行時提示報錯
System.out.println(ls.get(0));
}
}
java.lang.Integer cannot be cast to java.lang.String
Java允許直接把List對象賦給一個List<Type>(Type可以是任何類型)類型的變量,所以程序編譯通過,但對於list變量實際上引用的是List<Integer>集合,所以當試圖把該集合里的元素當成String類型的對象取出時,將引發
ClassCastException異常.
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM