Java tutorial on type erasure似乎没有详细说明编译器的强制转换插入的具体规则。有人可以解释导致本教程详述的转换的具体规则(转载如下):
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 = (MyNode)mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = (String)mn.data; // Causes a ClassCastException to be thrown.
具体来说,我想知道导致(MyNode)
和(String)
插入的规则是什么。何时插入了一个强制转换,以及如何为该强制转换选择该类型?
答案 0 :(得分:1)
<强> MyNode mn = new MyNode(5);
强>
MyNode
的实例,该实例将接口T
的通用类型Node
定义为Integer
<强> Node n = (MyNode)mn;
强>
T
并完全使用接口Node
而没有泛型会产生以下结果:想象泛型类型T
到被视为java.lang.Object
<强> n.setData("Hello");
强>
String
,Integer
,数组,其他任何内容) <强> Integer x = mn.data;
强>
nm.data
应该返回Integer
类型,因为Integer
被定义为T
类MyNode
String
的原始类型, nm.data
拥有String
个实例 ClassCastException
答案 1 :(得分:1)
调用
时ClassCastException
为throw
n.setData("Hello");
这是因为编译器构建了保持多态性的桥接方法。桥接方法如下:
public void setData(Object data) {
setData((Integer)data); //the exception is thrown here
}
由于字符串的实例无法转换为Integer
,因此会抛出ClassCastException
。
您可以阅读有关桥梁方法的问题here。