15.7 擦除的神秘之处

Java泛型是后来加入到语言中的,为了向前兼容,所以才有了擦除这个奇怪的同学。
但是真的感叹设计Java这门语言的设计师们,聪明的灵光一现。让我读到这里嘴角都是上扬的。这就是读书的乐趣与最聪明的人和大脑交谈。谢谢,你们。我站在巨人的肩膀上。

public class HasF {

    public void f() {

        System.out.println("HasF.f()"); 
    }
}

下面这个类不能通过编译。
obj.f() 根本不能通过编译。在编译阶段就会报错。
在Java中不可以,但是在C++中就可以。因为Java用的是擦除。

class Manipulator<T> {

    private T obj;

    public Manipulator(T x) {
        obj = x;
    }

    public void manipulate() {
        obj.f();  //  这里编译器会报错的
    }
}

↓↓↓
为了能通过编译可以这样
声明 T 必须是类型 HasF 或者 HasF的导出类型(也就是 HasF 的子类),那么就可以在 obj 上调用 f() 了。
↓↓↓

class Manipulator2<T extends HasF> {

    private T obj;

    public Manipulator2(T x) {
        obj = x; 
    }

    public void manipulate() {
        obj.f();
    }
}

这里一个巨重要且非常有意思的概念,就是“泛型类型参数将在编译的时候,擦除自己到第一个边界”
例如:class Manipulator2<T extends HasF> {
尖括号内 T extends HasF 那么边界就是HasF,编译完后尖括号内实际就被替换成了HasF。
书中原话是就好像在类的声明中用HasF替换了T一样。
<T>会被擦除为Object

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容