码迷,mamicode.com
首页 > 编程语言 > 详细

Java 中协变、类型擦除与桥接方法

时间:2020-10-24 11:40:34      阅读:30      评论:0      收藏:0      [点我收藏+]

标签:check   highlight   rgs   擦除   code   gem   特性   system   public   

协变

① 为什么数组是协变的?

jdk1.5 之前不支持泛型,,想要为每个数组类型添加通用的 equals方法,所以设计成是协变的。

② 为什么数组需要在运行时保留类型信息?

由于数组是协变的,利用其多态特性,即 Integer[]的实例对象可以赋给 Number[]类型的变量。则可以向该 Integer[ ] 实例放入Double类型的元素。因此保留类型信息则可在运行时检查出类型错误,从而阻止此类问题。

 

类型擦除

问题

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;
    }
}

class MyNode extends Node<Integer> {
    public MyNode(Integer data) {
        super(data);
    }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }
}

class Main {
    public static void main(String[] args) {
        MyNode mn = new MyNode(5);
        Node n = mn;            // A raw type - compiler throws an unchecked warning
        n.setData("Hello");
        Integer x=mn.data;
    }
}

 

桥接方法

编译后,由于类型擦除生成的一个辅助方法。

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);
    }
}

编译后

public class Node {

    public Object data;

    public Node(Object data) { this.data = data; }

    public void setData(Object data) {
        System.out.println("Node.setData");
        this.data = data;
    }
}

class MyNode extends Node {

    // Bridge method generated by the compiler
    //
    public void setData(Object data) {
        setData((Integer) data);
    }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }

    // ...
}

为了满足对象继承关系,生成立一个桥接方法。该桥接方法具有和 Node 类方法签名一致的方法,然后委托具体的类型方法。

 

233

参考资料


https://hongjiang.info/scala-type-system-array-type/#:~:text=scala%E9%87%8C%E4%B8%8D%E6%94%AF%E6%8C%81%E6%95%B0%E7%BB%84,%5BAny%5D%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8F%98%E9%87%8F%E3%80%82

https://zq99299.github.io/java-tutorial/java/generics/bridgeMethods.html#%E6%A1%A5%E6%8E%A5%E6%96%B9%E6%B3%95

Java 中协变、类型擦除与桥接方法

标签:check   highlight   rgs   擦除   code   gem   特性   system   public   

原文地址:https://www.cnblogs.com/lemos/p/13861819.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!