手撕JAVA(三十五)堆污染

堆污染是由于泛型的使用造成的一种潜在危险。

总结起来,堆污染就是因为使用泛型参数化类内部成员变量,同一类的不同实例对象内部里面成员变量的类型可能不同,

编译阶段无法发现,运行期间才能被发现的类型转换错误问题。

以下面一图说明泛型可能带来的堆污染问题:

手撕JAVA(三十五)堆污染

虚拟机栈将方法(method)压栈,局部变量表中的list1会在堆空间中通过new关键字开辟内存空间,

并将该片内存空间的地址引用返回给list1。

但是List是个类类型,其中具体存放元素的Object数组只是这个类的成员变量。但是JAVA的引用传递的检查机制是在类层面的。

也就是说用相同形状的映射相同形状的,形状里面的内容无关紧要。

所以编译阶段是不会出错的,因为Object类型的数组可以存放任何元素,但是在通过引用指向取出元素的时候就会报类型转换错误——integer无法转换成String。

因为ArrayList的底层源码里面在指定泛型的时候已经将返回值类型替换掉。list1、list2的相同方法返回值类型一个为integer一个为String。

手撕JAVA(三十五)堆污染