2012-09-09 112 views
1
package practice; 

class Node<T> { 

    T data; 

    public Node(T data) { this.data = data; } 

    public void setData(T data) { 
     System.out.println("Node.setData"); 
     this.data = data; 
    } 
} 

class MyNode extends Node<Integer> { 
    public MyNode(Integer data) { super(data); } 

    @Override 
    public void setData(Integer data) { 
     System.out.println("MyNode.setData"); 
     super.setData(data); 
    } 
} 

public class Practice { 
    public static void main(String[] s) 
    { 
     MyNode mn = new MyNode(5); 
     Node n = mn;   // A raw type - compiler throws an unchecked warning 
     n.setData("Hello");  // Causes a ClassCastException to be thrown. 
     Integer x = mn.data;  
    } 
} 

爲什麼在n.setData("Hello");這個代碼拋出異常時,實際上它應該扔在Integer x = mn.data;例外呢?泛型類型擦除ClassCastException異常

http://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html

回答

1

我認爲這是在本教程的一個小錯誤:他們應該說是錯誤的行n.setData("Hello");

拋出這是因爲,當你調用n.setData("Hello");調用電橋法:n.setData(Object object)MyNode類,否則你會有編譯時錯誤。

但橋方法是這樣的:

// Bridge method generated by the compiler 
// 
public void setData(Object data) { 
    setData((Integer) data); 
} 

你看到橋試圖與在data鑄造調用setData(Integer anInt)。由於您提供了String,因此此演員失敗。

這個例子中還有一個有趣的地方是,使用@Override註釋時沒有編譯時錯誤,即使你在技術上不覆蓋,但編譯器會在以後覆蓋。該註釋在此處非常有用,以通知setData(Object object)將被呼叫MyNode而不是Node。這解釋了爲什麼你沒有看到任何System.out消息。

2

因爲您正在嘗試設置字符串值到整型變量。

+0

請檢查編輯 – user1232138

1

您已經通過調用

MyNode mn = new MyNode(5); 

Integer類型定義的類型TNode。通過調用n.setData("Hello");,您正在嘗試爲Integer字段傳遞一個String變量。節點n僅僅是Integer型節點mn的參考。

+0

請檢查編輯 – user1232138

+0

有趣的是,該網頁上的一些代碼甚至沒有編譯,例如'Integer x =(String)mn.data;'但是一旦定義了類型,就不能在另一個類中「拉緊」。 – Reimeus

0

因爲n的類型實際上是Integer,它從mn收到。

這是同樣的原理List list = new ArrayList();

這裏的列表實際上是一個ArrayList,但只使用List接口引用。同樣,即使nNode,它的實施是MyNode,它只接受Integer。這就是爲什麼你可以把StringsetData()

閱讀編輯例子後

頁說,一橋方法如下創建:

class MyNode extends Node { 

    // Bridge method generated by the compiler 
    // 
    public void setData(Object data) { 
     setData((Integer) data); 
    } 

    public void setData(Integer data) { 
     System.out.println("MyNode.setData"); 
     super.setData(data); 
    } 

    // ... 
} 

橋方法做了如下

public void setData(Object data) { 
      setData((Integer) data); 
     } 

這裏它試圖投射的數據是String「你好」變成Integer。因此錯誤被拋出。

+0

請檢查編輯 – user1232138