zoukankan      html  css  js  c++  java
  • java泛型-类型擦除

    详细内容:参考java编程思想P373,p650.

    Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉;

        public class ErasedType{  
            Class c1 = List<String>().getClass();  
            Class c2 = List<Integer>().getClass();  
            System.out.print(c1 == c2);
       }          

    true;

    public class Foo {  
        public void listMethod(List<String> stringList){  
        }  
        public void listMethod(List<Integer> intList) {  
        }  
    } 

    Method listMethod(List<String>) has the same erasure listMethod(List<E>) as another method in type Foo

            此错误的意思是说listMethod(List<String>) 方法在编译时擦除类型后的方法是listMethod(List<E>),它与另外一个方法重复,也就是方法签名重复。反编译之后的方法代码如下:

    public void listMethod(List list)  
    {  
    } 

    从上面代码可以看出 Java 编译后的字节码中已经没有泛型的任何信息,在编译后所有的泛型类型都会做相应的转化,转化如下:

    • List<String>、List<T> 擦除后的类型为 List。
    • List<String>、List<T>[] 擦除后的类型为 List[]。
    • List<? extends E>、List<? super E> 擦除后的类型为 List<E>。
    • List<T extends Serialzable & Cloneable> 擦除后类型为 List<Serializable>。

            Java 为什么这么处理呢?有以下两个原因:

    1. 避免 JVM 的大换血。如果 JVM 将泛型类型延续到运行期,那么到运行期时 JVM 就需要进行大量的重构工作了,提高了运行期的效率。
    2. 版本兼容。 在编译期擦除可以更好地支持原生类型(Raw Type)。

            明白了 Java 泛型是类型擦除的,下面的问题就很好理解了:

            (1) 泛型的 class 对象是相同的

            每个类都有一个 class 属性,泛型化不会改变 class 属性的返回值;

         (2) 泛型数组初始化时不能声明泛型类型

        List<String>[] list = new List<String>[];  

    在这里可以声明一个带有泛型参数的数组,但是不能初始化该数组,因为执行了类型擦除操作后,List<Object>[] 与 List<String>[] 就是同一回事了,编译器拒绝如此声明。

            (3) instanceof 不允许存在泛型参数

            以下代码不能通过编译,原因一样,泛型类型被擦除了。

        List<String> list = new ArrayList<String>();  
        System.out.println(list instanceof List<String>);  

    错误信息如下: Cannot perform instanceof check against parameterized type List<String>. Use the form List<?> instead since further generic type information will be erased at runtime

  • 相关阅读:
    SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法
    备份还原工具—ghost
    太多的if,太多的痛苦
    C#中使用GUID
    WinForm开发中,将Excel文件导入到DataGridView中时,获取Excel中所有表格的名称。
    使用ASP调用C#写的COM+组件
    COM+ and the .NET Framework 虽是英文但比较全面
    在C#中使用COM+实现事务控制
    COM+ and the .NET Framework
    管理员ID过期,无人能够管理Domino服务器
  • 原文地址:https://www.cnblogs.com/chenglc/p/7496625.html
Copyright © 2011-2022 走看看