美文网首页
泛型擦除的问题

泛型擦除的问题

作者: 呆呆李宇杰 | 来源:发表于2017-09-13 00:17 被阅读117次

泛型的兼容性

因为泛型是在Java SE5的时候引入的,而为了兼容之前没有泛型的代码,而擦除是最好的兼容方法。
擦除的主要问题是将非泛化代码从泛化代码的的转变过程,继续使用,直至客户端准备好用泛型重写这些代码。这个动机不会破坏现有的代码。
擦除的代价也是显著的,泛型不能显示地引用运行时类型的操作之中,例如转型,instanceofnew表达式,这是因为所有关于参数的类型信息都丢失了。
所以无论何时,当在编写泛型代码的时候,必须时刻提醒自己,只是看起来具有有关参数的类型信息而已。
如果编写了以下的代码段。

class Foo<T> {
    T var;
}

那么,看起来当在创建Foo的实例时。

Foo<Cat> f = new Foo<Cat>();

class Foo中的代码应该知道现在工作于Cat之上,尽管如此,在编写代码的时候,就必须强烈地知道var只是一个Object类型。

擦除和迁移兼容性表明,使用泛型不是强制的。

class GenericBase<T> {
    private T element;

    public T getElement() {
        return element;
    }

    public void setElement(T element) {
        this.element = element;
    }
}

class Derived1<T> extends GenericBase<T> {
}

class Derived2 extends GenericBase {
}

//class Derived3 extends GenericBase<?> {
    // Strange error
//}

public class ErasureAndInheritance {

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        Derived2 d2 = new Derived2();
        Object obj = d2.getElement();
        d2.setElement(obj);// warning here
    }
}

上面的代码中,Derived2继承了GenericBase,但是没有任何泛型参数,但是编译器没有发出警告。而警告在set()被调用的时候才出现。
为了关闭警告,Java提供了一个注解(在Java SE5版本前不被支持)
@SuppressWarnings("unchecked")
需要注意的是,这个注解应该尽可能地被放置在可以产生这类警告的方法之上,而不是整个类上。当要关闭警告的时候,最好尽量地"聚焦,这样就不会过于宽泛地关闭警告,而导致意外地屏蔽掉真正的问题。
Derived3的错误意味着编译器期待得到的是一个原生基类,而不是一个不确定类型的类。
当希望将类型参数不仅仅当做Object处理的时候,就需要付出额外的努力去管理边界,并且与C++等语言获得参数化类型相比,需要付出多得多的努力来获得少得回报。这并不是说这些语言比Java更得心应手,而是说它们的参数类型化机制比Java更加强大、更灵活。

相关文章

  • [转载]泛型的内部原理:类型擦除以及类型擦除带来的问题

    泛型的内部原理:类型擦除以及类型擦除带来的问题

  • 【进阶之路】Java的类型擦除式泛型

    【进阶之路】Java的类型擦除式泛型 Java选择的泛型类型叫做类型擦除式泛型。什么是类型擦除式泛型呢?就是Jav...

  • 【开源项目】springfox-bridge采用多维递归结合ja

    springfox-bridge项目中,关于泛型问题,采用3个递归模型,动态生成泛型类的代理类,解决泛型擦除问题。...

  • 泛型擦除问题

    大家应该都有泛型在编译期会被擦除的概念,那么为什么我们在运行时还能读取到呢? 原因是因为编译器帮我们完成了自动类型...

  • 泛型

    泛型用于编译时期,确保类型的安全 在运行时,会将泛型去掉,class文件是不带泛型的,这个称为泛型的擦除,擦除是为...

  • 泛型擦除的问题

    泛型的兼容性 因为泛型是在Java SE5的时候引入的,而为了兼容之前没有泛型的代码,而擦除是最好的兼容方法。擦除...

  • Android 开发也要掌握的Java知识 - Java泛型

    如果需要看泛型擦除Java泛型擦除 1.Java泛型有什么用?为啥要使用泛型? Java中数组的类型是定义的时候就...

  • JAVA泛型和类型擦除

    什么是类型擦除 Java是使用擦除来实现泛型的。使用泛型后在运行时任何具体的类型信息都被擦除了,关于泛型的处理都是...

  • java泛型

    java的泛型是"伪泛型",为什么这么说。因为泛型只是作用在编译之前,编译之后,泛型都被擦除了(类型擦除)。所以说...

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

网友评论

      本文标题:泛型擦除的问题

      本文链接:https://www.haomeiwen.com/subject/dfphsxtx.html