开发者社区> 问答> 正文

关于泛型擦除,你知道多少?

关于泛型擦除,你知道多少?

展开
收起
问问小秘 2020-06-23 14:47:19 1132 0
1 条回答
写回答
取消 提交回答
  • 类型擦除会出现在泛型方法中,程序员通常认为下述的泛型方法

    public static <T extends Comparable> T min(T[] a)
    

    是一个完整的方法族,而擦除类型之后,只剩下一个方法:

    public static Comparable min(Comparable[] a)
    

    这个时候类型参数T已经被擦除了,只留下了限定类型Comparable

    但是方法的擦除会带来一些问题:

    class Coupling extends Couple<People> {
        public void setTwo(People people) {
                super.setTwo(people);
        }
    }
    

    擦除后:

    class Coupling extends Couple {
        public void setTwo(People People) {...}
    }
    

    这时,问题出现了,存在另一个从Couple类继承的setTwo方法,即:

    public void setTwo(Object two)
    

    这显然是一个不同的方法,因为它有一个不同类型的参数(Object),而不是People

    Coupling coupling = new Coupling(...);
    Couple<People> cp = interval;
    cp.setTwo(people);
    

    这里,希望对setTwo的调用具有多态性,并调用最合适的那个方法。由于cp引用Coupling对象,所以应该调用Coupling.setTwo。问题在于类型擦除与多态发生了冲突。要解决这个问题,就需要编译器在Coupling类中生成一个桥方法:

    public void setTwo(Object second) {
        setTwo((People)second);
    }
    

    变量cp已经声明为类型Couple,并且这个类型只有一个简单的方法叫setTwo,即setTwo(Object)。虚拟机用cp引用的对象调用这个方法。这个对象是Coupling类型的,所以会调用Coupling.setTwo(Object)方法。这个方法是合成的桥方法。它会调用Coupling.setTwo(Date),这也正是我们所期望的结果。

    2020-06-23 14:47:34
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载