代码之家  ›  专栏  ›  技术社区  ›  Hearen

必要时插入类型转换以保持类型安全[重复]

  •  -1
  • Hearen  · 技术社区  · 6 年前

    爪哇 tutorial on type erasure 似乎没有详细说明编译器强制转换插入的特定规则。有人能解释一下导致本教程详细介绍的转换的具体规则吗(转载如下):

    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) . 何时插入转换,如何为转换选择类型?

    0 回复  |  直到 6 年前
        1
  •  1
  •   Crazyjavahacking    10 年前
    1. MyNode mn = new MyNode(5);

      • 将创建的实例 MyNode 它定义了泛型类型 T 界面的 Node 作为 Integer
      • 强制转换:开发人员不需要强制转换,编译器不添加强制转换
    2. Node n = (MyNode)mn;

      • 这基本上会告诉编译器忘记泛型类型 T 使用接口 结点 完全没有将产生以下后果的泛型: 想象泛型类型 T 作为 java.lang.Object
      • 强制转换:开发人员不需要强制转换,编译器不添加强制转换
    3. n.setData("Hello");

      • 将允许您添加任何类型的ob对象 因为t被当作物体( String , 整数 ,数组,其他任何内容)
      • 强制转换:开发人员不需要强制转换,编译器不添加强制转换
    4. Integer x = mn.data;

      • nm.data 应该返回一个 整数 类型为 整数 定义为泛型类型参数 T 小精灵
      • 但是,因为您使用的原始类型允许您添加 相反, NM数据 持有 实例
      • 强制转换:开发人员不需要强制转换,但是编译器会在后台为您将强制转换添加到integer,并且由于类型不匹配,您将得到 ClassCastException
        2
  •  1
  •   Hearen    6 年前

    这个 ClassCastException 将是 throw 当打电话给

    n.setData("Hello");
    

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

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

    因为字符串的实例不能转换为 Integer , the 类别例外 会被扔掉。

    你可以阅读桥梁方法 here .