繁体   English   中英

Java类型擦除:强制转换插入规则?

[英]Java Type Erasure: Rules of cast insertion?

关于类型擦除的Java 教程似乎并未详细说明编译器强制转换的特定规则。 有人可以解释一下导致本教程详细介绍的转换的特定规则(如下所示):

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)的插入。 什么时候插入演员表,以及如何选择演员表类型?

  1. MyNode mn = new MyNode(5);

    • 将创建MyNode的实例,该实例将接口Node的通用类型T定义为Integer
    • 强制转换:开发人员无需强制转换,编译器无需添加强制转换
  2. Node n = (MyNode)mn;

    • 这基本上将告诉编译器忘记泛型T并完全使用接口Node而不使用泛型,这将产生以下结果: 假设将泛型T视为java.lang.Object
    • 强制转换:开发人员无需强制转换,编译器无需添加强制转换
  3. n.setData("Hello");

    • 将允许您添加任何种类的ob对象,因为T被视为Object( StringInteger ,array等)
    • 强制转换:开发人员无需强制转换,编译器无需添加强制转换
  4. Integer x = mn.data;

    • nm.data应该返回一个Integer类型,因为在MyNode类中Integer被定义为泛型类型参数T
    • 但是,因为使用的原始类型允许您添加String ,所以nm.data保存了String实例
    • 强制转换:开发人员无需强制转换,但是编译器将为您在后台将强制转换添加到Integer,并且由于类型不匹配,您将获得ClassCastException

调用时会throw ClassCastException

n.setData("Hello");

这是因为编译器会构建桥接方法来保留多态。 桥接方法如下所示:

 public void setData(Object data) {
       setData((Integer)data);   //the exception is thrown here
  }

由于不能将字符串的实例转换为Integer ,因此将引发ClassCastException

您可以在此处阅读有关桥接方法的信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM