关注我,每天三分钟,带你轻松掌握一个Java相关知识点。
在之前的文章中,我们介绍过泛型的概念以及使用方法。评论区中有小伙伴说没有介绍泛型擦除的概念不能说把泛型介绍完了,那我们今天来说说泛型的类型擦除。
其实关于Java使用的泛型是不是真泛型,业内还有很多争论。大佬Bruce Eckel还曾经专门写了一篇文《这不是泛型!》来喷JDK实现的泛型,什么?你没听过这个人,那你一定听过他写的书——《Thinking in Java》。
为什么说JDK实现的是个假泛型呢?
其实早在C++时代,泛型的思想就开始萌芽了,当时Java还没有考虑过这块。比如早先在Java中,HashMap的get方法取出来的对象就是一个Object,这个玩意儿可能是任何类型的值,在编译期间,编译器根本不能检查这个Object的类型转换过程,只能依靠人,这就很不靠谱,好多错都是到了运行期间才被发现的。
如果说JDK是假泛型,真泛型是什么样的呢?C#中的泛型,无论在程序源码、编译后的中间语言,还是在运行期的CLR中,都是切实存在的,List和List就是两种类型,他们在系统运行期生成,有自己的需方发表和类型数据,这种实现成为类型膨胀,给予这种方法实现的泛型成为真实泛型。
而Java呢,它的泛型只存在于程序源码中,在编译完的字节码文件中,就已经替换成原来的原生类型了,并且在相应的地方加了强制类型转换,对于运行期的Java程序来说,List和List就是一种类型,这就是大家所说的类型擦除。
如何证明呢?有一道很经典的面试题:
List l1 = new ArrayList();
List l2 = new ArrayList();
System.out.println(l1.getClass() == l2.getClass());
大家可以先想一下,这个输出结果是什么呢?
没错,是true,这就是类型擦除导致的。
还有一个很好的证明就是重载:
public void A(List t)
public void A(List t)
按说参数不同符合Java的方法重载要求,但打脸的是,编译都无法通过,因为JDK编译完后发现两个方法是同样参数的。
还有要跟大家补充的一点,这也是之前文章中忘了提醒小伙伴们,泛型不支持基本数据类型。
像List List都是不行的,要是想用就用它的包装类Integer和Boolean。
以上就是今天的知识点,各位小伙伴get到吗?创作不易,望各位多多点赞收藏,有什么建议可以留言告诉我,我会积极采纳!