美文网首页
关于JAVA泛型的理解

关于JAVA泛型的理解

作者: 一个坏人_9c31 | 来源:发表于2017-12-12 21:44 被阅读0次

              关于java泛型的理解,泛型是java5.0增加的一种新的机制,与c++的模板很相似但却有很多的不同,当然我对c++的理解并不多,对于java泛型的理解我从以下几个方面总结一下,当然,也许会有错误,毕竟学习还不是很深刻,仅阶段性总结。

    为什么要引入泛型:

          在泛型出现之前java中当然也是有一个ArrayList用来存储各种对象,对于代码可读性是一个问题,最重要的是对于使用ArrayList的安全性有很严重的问题,由于要适应存储各种类型变量,ArrayList内部使用Object来存放对象,这就产生了两个问题,<1>如果你只想存入String类型,但存入的对象可以是任何其他对象。<2>取出时要进行强制类型转换,结合第一点,你并不知道你要转换的可能并不是你想要的,此时就要出错。并且这些错误并不会在你编译时提示你。因此,引入泛型就显得很必要。

    泛型的实现原理:

            泛型中用<>来限定类型变量,如ArrayList,既然限定了类型变量,当然就很好的解决了之前的痛点,在进行编译时,只能存储读取已经指定类型的变量,当你试图存储其他类型的变量时,编译器便会报错,这在安全性与可读性上都有了很大的改变。

            然而,java中的泛型仅是一种伪泛型,这也是他与c++中模板类本质的区别,jvm虚拟机中并不存在泛型这种对象,泛型的“存活期”仅在程序进行编译前,或许可以这样说,java的泛型是通过编译器来实现的。

            这里要提到两个名词“原始类型”与“类型擦除”这是理解泛型极为重要的两个概念。所谓类型擦除应该很容易理解

    例如:

    ```

    test

    ```

      进行类型擦出后,则变为:

         类型参数被擦除后的代码便是原始类型,每一个泛型都对应一个原始类型。

         那么问题来了,将参数擦出之后,存取时还怎么识别限定参数类型,编译器会替我们做这一切,当调用demo.getT()方法时会返回一个object对象,编译器会在翻译程序时会在方法调用后插入一条强制类型转换指令对于set()方法,在编译程序前会由编译器对泛型进行检查,当引用的不是限定的类型变量时,编译器就会报错。由此,这些对于我们来说都是不可见的。

           然而类型擦除造成了继承上的一些问题,例如:

         该方法继承并重写了父类方法中的get,set方法,那么在编译进行类型擦除后如何保证多态特性,以及方法的签名问题,加入直接进行擦出会直接产生两个setT(Object)与Object get()方法。此时编译器会为我们出现冲突的程序添加一个“桥方法”,表面解读就是桥梁的意思,添加桥方法后编译后程序中拥有的方法为:

        乍一看有点奇怪,第一个和第三个方法都是编译器替你添加的桥方法,setT()还能理解,但getT()难道不会签名冲突,如果是我们自己写当然不会通过编译,但是在虚拟机运行时这样的写法是正确的,虚拟机会根据返回的参数来确定你调用的是哪个方法。

    相关文章

      网友评论

          本文标题:关于JAVA泛型的理解

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