首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java上的Erasure教程类型

Java上的Erasure教程类型
EN

Stack Overflow用户
提问于 2016-03-13 12:09:56
回答 2查看 166关注 0票数 3

我正在阅读关于甲骨文(类型擦除)的泛型线索,我无法理解下面的部分。

代码片段如下所示:

代码语言:javascript
复制
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);
    }
}

这条线索提到以下几点:

考虑以下代码:

代码语言:javascript
复制
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.

类型删除后,此代码将变为:

代码语言:javascript
复制
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("Hello");导致在类MyNode的对象上执行setData(对象)方法。( MyNode类从Node继承了setData(对象)。)
  • 在setData( object )的主体中,n引用的对象的数据字段被赋值为字符串。
  • 通过mn引用的同一对象的数据字段可以被访问,并被期望为整数(因为mn是一个MyNode,它是一个节点)。
  • 试图将字符串分配给Integer会导致ClassCastException从在赋值时插入的强制转换中由Java编译器插入。

我无法理解为什么试图检索数据会导致异常。就我的理解而言,不应该设置数据本身,抛出异常(这是在我的编译器上发生的事情,但是由于我没有使用Oracle的编译器,所以我不确定哪一个是正确的)?

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

代码语言:javascript
复制
void setData(Object); //bridge method
void setData(Integer);

因此,在Node上调用setData(Object)应该正确地调用MyNode中的桥接器方法,后者反过来调用setData(Integer),这是应该抛出类强制转换异常的地方。但甲骨文的教程却不假思索地说,事实并非如此。那么我的理解有什么问题呢?请帮我理解一下。

EN

回答 2

Stack Overflow用户

发布于 2016-03-13 12:30:33

如果我的理解是正确的,那么类MyNode应该有两个方法 空洞setData(对象);//桥方法 无效setData(整数);

那是真的。MyNode类将具有上述两种方法。

javap上做MyNode.class也显示了这一点。请参阅在**之间突出显示的以下两种方法

代码语言:javascript
复制
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);**
}

因此,在Node上调用setData(Object)应该正确地调用MyNode中的桥接器方法,后者反过来调用setData(Integer),这是应该抛出类强制转换异常的地方。

这也是事实。调用它会导致以下异常:

代码语言:javascript
复制
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)

MyNode.java:14是我给n.setData("Hello");打电话的地方

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

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

票数 0
EN

Stack Overflow用户

发布于 2019-06-21 09:55:31

我昨天在看文件的时候发现了这个。我在Oracle跟踪器中打开了这个错误,并添加了这个问题作为参考。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35970031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档