Java类型擦除

来源:互联网 发布:标签系统数据库设计 编辑:程序博客网 时间:2024/05/09 02:50
public class LXCC {    /**     * 类型擦除     * 泛型在很大程度上是Java语言中的成分而不是虚拟机中的结构,泛型类可以由编译器通过所谓的类型擦除     * (type erasure)过程而转变成非泛型类,这样,编译器就生成一种与泛型类同名的原始类(raw class)     * 但是类型参数都被删除去了,类型变量由他们的类型限界来代替,当一个具有擦除返回类型的泛型方法被     * 调用的时候,一些特性被自动的插入,如果使用一个泛型类而不带类型参数,那么使用的是原始类     * 类型擦除的一个重要的理论是,所生成的代码与程序员在泛型之前所写的代码没有太多的差异,而且事实     * 上运行的雨布快,其显著的优点在于,程序员不必把一些类型转换放到代码中,编译器将进行重要的类型     * 检验     * ---     * 对于与泛型的限制     *       对于泛型类型有许多限制,由于类型擦除的原因,这里列出的每一个限制都是必须要遵守的     * 基本类型     *  基本类型不能用做类型参数,因此,GenericMeoryCell<int> 是非法的,我们必须使用包装类     *  GenericMeoryCell<Integer>     * instanceof检测     *    instanceof检测和类型转换工作只对原始类进行,在下列代码中:     *    GenricMeoryCell<Integer> cell=new GenericMeoryCell<Integer>();     *    cell.write(4);     *    Object cell=cell;     *    GenericMeoryCell<String> cell2=(GenericMeoryCell<String>) cell;     *    String s=cell2.read();     *    这里的类型转换在运行时是成功的,因为所有的类型都是GenericMeoryCell,但在最后一行,由于     *    对read的调用企图返回一个String对象从而产生一个运行时错误,结果,类型转换将产生一个警告     *    而对应的instanceof检测是非法的     *    static的语境     *       在一个泛型类中,static方法和static域均不可引用类的类型变量,因为在类型擦除后类型变量     *       就不存在了,另外,由于实际上只存在一个原始的类,因此static域在该类型的诸泛型实例之间是     *       共享的     *     泛型类型的实例化     *          不能创建一个泛型类型的实例,如果T是个类型变量,则语句     *          T obj =new T();  右边是非法的     *          是非法的,T由于他的界限代替,这可能是Object(或甚至是抽象类),因此对于new的调用没有任何意义     *     泛型数组对象     *       也不能创建一个泛型的数组,如果T是一个类型变量,则语句     *        Y [] ARR=new T[10];  右边是非法的     *        T 将由他的界限代替,这可能Object T 于是(由类型擦除产生的)对T【】的类型的转换将无法进     *        because Object[] IS-NOT-A T[] ,s由于我们不能创建泛型对象数组,因此一般来说,我们必须     *        创建一个擦除类型数组,然后使用类型转换,这种类型转换将产生一个关于未检验的类型转化的编译警告     *  参数化的类型的数组     *      参数化类型的数组的实例化是非法的,     *      GenericMeoryCell<String>[] arr1=new GenericMeoryCell<String>[10];     *      GenericMeoryCell<Double> cell=new GenericMeoryCell<Double>();cell.write(4.5)     *      Object[] arr2=arr1[];     *      arr2[0]=cell;     *      String s=arr1[0].read();     *    正常情况下我们认为第4行的赋值会产生一个ArrayStoreException     *    正常情况下我们认为第4行的赋值会产生一个ArrayStoreExceptio,因为赋值的类型有错误     *    可是,在类型擦除之后,数组的类型GenericMeoryCell【】,而加到数组中的对象也是GenericMeoryCell     *    因此不存在,ArrayStoreException异常,于是该段代码没有类型转换,他最终将在第五行产生一个     *     ClassCaseException异常,这正是泛型应该避免的错误     *     */}
0 0