2012-09-09 164 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