您的位置 首页 java

什么?Java的泛型是伪泛型

泛型 是JDK 1.5的一项新增特性,它的本质是参数化类型(ParametersizedType)的应用,也就是说所操作的数据类型被指定为一个参数(是不是像lambda表达式差不多的用义,用函数作为一个方法的参数)。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。

具体来说,我们先通过对比下代码,来进一步体会泛型的好处

先看看没有支持泛型之前的代码

什么?Java的泛型是伪泛型

1.5之前的代码示范

什么?Java的泛型是伪泛型

引入泛型后的代码示范

由以上两个例子可以看出:

引入泛型后,代码在前端编译的时候会做检查,不会像1.5的代码示范一样,直到程序运行期才提示异常。通过现代 idea 自动编译功能,由此可以大大提高我们的编程效率

但是有关 java 的泛型有一些值得思考的问题:

什么?Java的泛型是伪泛型

方法重载

什么?Java的泛型是伪泛型

编译异常

代码示范:用两个不同List类型参数重载getName方法编译报错,why?

以上现象是因为在编译时泛型擦除造成的,什么? 泛型擦除又是什么鬼?

我们可以通过 字节码 来分析这个问题

什么?Java的泛型是伪泛型

泛型代码示范

什么?Java的泛型是伪泛型

部分字节码

然后用jd-gui工具 反编译 回java代码

什么?Java的泛型是伪泛型

反编译的代码

通过对比可以看出,反编译的代码跟我们之前写的代码不一致了,代码风格也用回1.5之前的强制类型转换了,即高版本支持某些语法糖的编程风格编译之后转化为低版本代码风格了(解语法糖)

现在我们可以知道为什么用两个不同List类型参数重载getName方法会编译报错了:

两个不同List类型参数,在编译的时候都转为List<Object>了,然后就不符合重载的定义了

所以有个哲学上的问题:

List<Integer>

List<String>

其实这两个类型不是真正意义上的类型,他们在某种意义上还是一个List类型,只是套了层修饰,这种表面上的修饰作用很有利于编程人员,过了编译期,这种修饰就没有意义了,当然,为了运行期反射来获取这种修饰符号,在编译成字节码时,增加了一些属性来记录这个具体的类型,解决伴随泛型而来的参数类型的识别问题,如如Signature、LocalVariableTypeTable

什么?Java的泛型是伪泛型

LocalVariableTypeTable和Signature

所以有个说法是: java实现的泛型,其实不是真正意义上的泛型,是伪泛型

文章来源:智云一二三科技

文章标题:什么?Java的泛型是伪泛型

文章地址:https://www.zhihuclub.com/182162.shtml

关于作者: 智云科技

热门文章

网站地图