【发布时间】:2016-03-13 12:09:56
【问题描述】:
我正在阅读 Oracle (Type Erasure) 上的泛型跟踪,但无法理解以下部分。
sn-ps代码如下:
public class Node<T> {
public T data;
public Node(T data) { this.data = data; }
public void setData(T data) {
System.out.println("Node.setData");
this.data = data;
}
}
public class MyNode extends Node<Integer> {
public MyNode(Integer data) { super(data); }
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
}
线索提到以下内容:
考虑以下代码:
MyNode mn = new MyNode(5);
Node n = mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = mn.data; // Causes a ClassCastException to be thrown.
类型擦除后,这段代码变成:
MyNode mn = new MyNode(5);
Node n = (MyNode)mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = (String)mn.data; // Causes a ClassCastException to be thrown.
引用同一个教程 -
这是代码执行时发生的情况
- n.setData("你好");导致方法 setData(Object) 被执行 在 MyNode 类的对象上。 (MyNode 类继承 来自节点的 setData(Object)。)
- 在setData(Object) 的主体中,n 引用的对象的数据字段被分配给一个String。
- 通过 mn 引用的同一对象的数据字段可以访问,并且应该是一个整数(因为 mn 是一个 MyNode,它是一个节点。
- 尝试将 String 分配给 Integer 会导致 Java 编译器在分配时插入的强制转换引发 ClassCastException。
我无法理解为什么尝试检索数据会导致异常。据我了解,不应该设置数据本身引发异常(这是我的编译器发生的情况,但由于我没有使用 Oracle 的编译器,我不确定哪个是正确的)?
如果我的理解是正确的,MyNode 类应该有两种方法:
void setData(Object); //bridge method
void setData(Integer);
所以在 Node 上调用 setData(Object) 应该正确地调用 MyNode 中的 bridge 方法,该方法又调用 setData(Integer) ,这是应该抛出类转换异常的地方。但是甲骨文的教程特意说事实并非如此。那么我的理解有什么问题呢?请帮我理解。
【问题讨论】:
-
是的,看来教程是错误的。
setData应该抛出运行时错误。
标签: java generics type-erasure java-bridge-method