1. 程式人生 > >Java泛型的轉型

Java泛型的轉型

泛型是Java SE中比較複雜的內容了,而擦除和轉型又是泛型中比較複雜的內容,這裡總結了泛型關於轉型的一些知識,其中還涉及到了一點擦除。

public class myFixed {

    public static void main(String[] args) {
        Fixed<String> stringFixed = new Fixed<>();
        stringFixed.push("abc");
        stringFixed.push("abc1");
        stringFixed.push(123);
stringFixed.push(456); Object obj1 = stringFixed.<String>pop(); System.out.println(obj1.getClass() + " " + obj1); Integer i =(Integer) obj1; System.out.println(i.getClass().toString() + " " + i); String obj = stringFixed.pop(); System.out
.println(obj.getClass().toString() + " " + obj); // obj = stringFixed.pop(); // System.out.println(obj.getClass().toString() + " " + obj); // obj = stringFixed.pop(); // System.out.println(obj.getClass().toString() + " " + obj); } static class Fixed<T> { Object[] objects = new Object[10
]; int index = 0; void push(Object object){ objects[index++] = object; } @SuppressWarnings("unchecked") T pop(){ Object obj = objects[--index]; T t =(T) obj; return t; } } }

在程式碼29行中實際上並沒有發生轉型,因為在編譯的時候T就會被擦除了,所以編譯器無法知道這個轉型是否安全,所以會產生“unchecked cast”警告,通過@SuppressWarnings(“unchecked”)註解消除警告;並且由於擦除T在執行時相當於Object,所以這裡實際上只是將Object轉型為Object。實際上的轉型發生在11行和13行這樣的情況。String obj = stringFixed.pop();pop()返回的是Object,這裡自動發生強轉。此時從 int 到 string 強轉失敗,會崩潰。處理方式如下:

Object obj1 = stringFixed.pop();
        System.out.println(obj1.getClass() + " " + obj1);
        Integer i =(Integer) obj1;

stringFixed的泛型型別引數是String,pop傳遞回來了一個String的偽裝,所以Integer obj1 = stringFixed.pop();編譯不會通過,儘管pop()事實返回的是一個Object型別(執行時型別為Integer);所以用String接收編譯能通過,但是執行會崩潰(當pop()執行時返回的是String型別時就正常執行);正確做法應該用Object接收返回結果,然後在強轉為執行時返回的型別。