「java擦除」java擦除后如何找到实际类型
今天给各位分享java擦除的知识,其中也会对java擦除后如何找到实际类型进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
java为什么要用类型擦除实现泛型
因为设计者在引入泛型概念的时候就是这么做的,成本较低,后来尽管jdk不断升级,但是考虑到要兼容老系统,所以一直也不敢去改变这种伪泛型的机制
下面的java代码每次重绘的时候,之前的红色的圆没有被擦除掉,是怎么回事?
repaint确实重新画了,但是并不会擦掉以前画的内容。\x0d\x0a在重写的那个paint方法中第一行加上如下一句:\x0d\x0ag.clearRect(0, 0, this.getWidth(), this.getHeight()); \x0d\x0a//把你之前画的内容删掉\x0d\x0a\x0d\x0arepaint() 方法具有的功能仅仅就是 重新调用一次paint() 方法而已。
27.Android架构-泛型擦除机制
Java的泛型是JDK5新引入的特性,为了向下兼容,虚拟机其实是不支持泛型,所以Java实现的是一种
伪泛型机制,也就是说Java在编译期擦除了所有的泛型信息,这样Java就不需要产生新的类型到字节码,
所有的泛型类型最终都是一种原始类型,在Java运行时根本就不存在泛型信息。
使用ASM ByteCode Viewer查看他的字节码
可以看到我们设置的泛型R,被擦除为Object了,这就是泛型擦除
他的bytecode为
可以看到我们限定了泛型的类型,那么他的bytecode是什么样的?
可以看到虽然我们在Plate2中只定义了一个set get方法,但是bytecode中却有两个,其中一个get set方法添加了synthetic bridge 表示这是一个桥接方法,作用是为了保持多态性,可以看到 CHECKCAST java/lang/Comparable ,检查类型是否为Comparable,如果是的话再去调用上边的 public set(Ljava/lang/Comparable;)V 方法。可以这样理解, set(Ljava/lang/Object;)V 是从Plate接口实现来的, set(Ljava/lang/Comparable;)V 是他本身的,因为限定了类型范围
上边我们是通过showbytecode的方式查看的字节码,但是如果你点开类生成的class文件,你会发现,泛型既然被擦除了为什么在class中仍然可以看到?其实这里看到的只是签名而已,还保留了定义的格式,这样对分析字节码有好处。你甚至可以通过javap -c Plate2.class反编译class,你会发现,R还是能被看到,我们要看bytecode,通过showbytecode的方式比较真实
比如没有ArrayListint,只有ArrayListInteger.当类型擦除后,ArrayList的原始类中的类型变量(T)替换成Object,但Object类型不能 存放int值
因为擦除后,ArrayListString只剩下原始类型,泛型信息String不存在了,所有没法使用instanceof
因为泛型类中的泛型参数的实例化是在定义泛型类型对象 (比如ArrayListInteger)的时候指定的,而静态成员是不需要使用对象来调用的,所有对象都没创建,如何确定这个泛型参数是什么
因为擦除后两个equals方法变成一样的了
因为类型不确定
因为数组是协变( 在某些情况下,即使某个对象不是数组的基类型,我们也可以把它赋值给数组元素。这种属性叫做协变(covariance) ),擦除后就没法满足数组协变的原则
java什么叫泛型擦除
泛型是1.5中引入的一个新的概念,由于不用进行强制转换类型了,所以具有较高的安全性和易用性。因为泛型其实只是在编译器中实现的而虚拟机并不认识泛型类项,所以要在虚拟机中将泛型类型进行擦除。也就是说,在编译阶段使用泛型,运行阶段取消泛型,即擦除。 擦除是将泛型类型以其父类代替,如String 变成了Object等。其实在使用的时候还是进行带强制类型的转化,只不过这是比较安全的转换,因为在编译阶段已经确保了数据的一致性。
关于java擦除和java擦除后如何找到实际类型的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-11-27,除非注明,否则均为
原创文章,转载请注明出处。