我正在审查一个名为“
Effects of Type Erasure and Bridge Methods”的Java泛型Oracle路径,我无法说服自己给出解释.好奇,我在本地测试了代码,我甚至无法重现跟踪解释的行为.这是相关的代码:
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); } }
Oracle跟踪声明此代码段的以下行为:
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.
我不明白这里使用的演员表或行为.当我尝试使用IntelliJ和Java 7本地运行此代码时,我遇到了这种情况:
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;
换句话说,JVM不允许String与setData()一起使用.这对我来说实际上是直观的,它同意我对泛型的理解.由于MyNode mn是用Integer构造的,因此编译器应该使用Integer转换对setData()的每次调用,以确保类型安全(即传入Integer).
有人能否对Oracle踪迹中的这个明显错误有所了解?