Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java上的类型擦除教程_Java_Generics_Type Erasure_Java Bridge Method - Fatal编程技术网

Java上的类型擦除教程

Java上的类型擦除教程,java,generics,type-erasure,java-bridge-method,Java,Generics,Type Erasure,Java Bridge Method,我正在阅读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; } } p

我正在阅读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);
    }
}
类型擦除后,此代码变为:

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(对象) 在类MyNode的对象上。(MyNode类继承了 从节点设置数据(对象)
  • 在setData(Object)的主体中,n引用的对象的数据字段被分配给一个字符串
  • 通过mn引用的同一对象的数据字段可以访问,并且应该是一个整数(因为mn是一个MyNode,它是一个节点)
  • 尝试将字符串分配给整数会导致Java编译器在分配时插入的强制转换产生ClassCastException
我无法理解为什么试图检索数据会导致异常。就我的理解而言,设置数据本身不应该引发异常(这是在我的编译器上发生的情况,但由于我没有使用Oracle的编译器,我不确定哪个是对的)

如果我的理解是正确的,那么MyNode类应该有两种方法:

void setData(Object); //bridge method
void setData(Integer);
因此,在节点上调用setData(Object)应该正确地调用MyNode中的bridge方法,该方法反过来调用setData(Integer),这是类强制转换异常应该抛出的位置。但是Oracle的教程特意说,情况并非如此。那么,我的理解有什么问题?请帮助我理解

如果我的理解是正确的,那么MyNode类应该有两个方法
void setData(Object);//桥接方法
void setData(整数)

这是真的。MyNode类将有以上两个方法

MyNode.class
上执行
javap
也会显示它。请参见下面突出显示的两种方法**

javap MyNode.class
Compiled from "MyNode.java"  
public class com.demo.generics.demo.MyNode extends com.demo.generics.demo.Node<j
ava.lang.Integer> {
  public com.demo.generics.demo.MyNode(java.lang.Integer);
  **public void setData(java.lang.Integer);**
  public static void main(java.lang.String[]);
  **public void setData(java.lang.Object);**
}
MyNode.java:14
是我调用的
n.setData(“Hello”);

这是在我的编译器上发生的,但由于我没有使用Oracle的编译器,我不确定哪一个是正确的)


这不依赖于编译器,应该是相同的。

我昨天在阅读文档时遇到了这个问题。我在Oracle bug tracker中打开了这个问题,并添加了这个问题作为参考。

那么教程错了吗?我想他们只需要得到通知,这样他们就可以更新他们的教程了。顺便问一下,你在使用Oracle的编译器吗?@AshishDaggubatti我将浏览教程并对其进行评论。是的,我的是一个Oracle JDK。@AshishDaggubatti-hmm。我看教程在何时确切地引发
ClassCastException
这个问题上有误导性。一方面,它显示了一个
ClassCastException
将在
Integer x=mn.data处出现,这似乎是自相矛盾的
语句,随后在结尾表示生成的
桥接方法将调用
setData((整数)数据)
理想情况下,这是真正引发
ClassCastException
的点。除非我们误解了教程,我怀疑:-)是的,看起来教程是错的
setData
应引发运行时错误。
javap MyNode.class
Compiled from "MyNode.java"  
public class com.demo.generics.demo.MyNode extends com.demo.generics.demo.Node<j
ava.lang.Integer> {
  public com.demo.generics.demo.MyNode(java.lang.Integer);
  **public void setData(java.lang.Integer);**
  public static void main(java.lang.String[]);
  **public void setData(java.lang.Object);**
}
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at com.demo.generics.demo.MyNode.setData(MyNode.java:1)
    at com.demo.generics.demo.MyNode.main(MyNode.java:14)