关于Java泛型的Oracle之一的潜在问题

Tim*_*sen 7 java generics type-erasure

我正在审查一个关于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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

在类型擦除后,此代码段应如下所示:

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.
Run Code Online (Sandbox Code Playgroud)

我不明白这里使用的演员表或行为.当我尝试使用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;
Run Code Online (Sandbox Code Playgroud)

换句话说,JVM将不允许String使用setData().这对我来说实际上是直观的,它同意我对泛型的理解.由于MyNode mn构造有Integer,编译器应该每次调用setData()with Integer以确保类型安全(即Integer传入一个).

有人能否对Oracle踪迹中的这个明显错误有所了解?

Ada*_*dam 3

您误读了 Oracle 页面。如果你从头到尾读完,你会发现它指出发生的事情就是你所描述的。

这不是一个写得很好的页面;作者说“废话发生了”,而他们的意思是“如果是这种情况,那么废话就会发生,但正如我们所见,情况并非如此”。他们的语言过于宽松。

该页面的要点 - 桥接方法 - 是解释当预测的行为(基于泛型实际设计+实现)是他们在开始时“建议”的行为时,真实的行为是如何如您所观察到的。