泛型的擦除和转换:
1. 泛型的擦除
泛型编译后就消失了(泛型自动擦除):如下
创建一个点类,具有x和y坐标的属性,但我们不知道坐标具体是整型还是浮点型还是字符串,所以我们就要泛型类来表示public class Point<T> { private T x; private T y; public T getX() { return this.x; } public void setX(T x) { this.x = x; } public T getY() { return this.y; } public void setY(T y) { this.y = y; } }
新建一个Demo来演示Point的使用
public class PointDemo { public static void main(String[] args) { Point<String> p = new Point<String>(); String x = p.getX(); System.out.println(x); } }
反编译Demo后发现Java代码如下图
从中我们可以发现,编译器还是用强制类型转换为我们实现了泛型
当把带有泛型的集合赋给不带泛型的集合时,此时泛型被擦除(手动擦除):如下图
list1集合虽然设定为Integer类型,但由于list2未设定类型(使用默认的Object类型),所以在list1赋值为list1的时候,先把list1中的类型擦除了,然后转换成Object
第二种类型的泛型转换并不是安全的,容易造成堆污染
如下图
//带有泛型的集合
List<Integer> list1 = new ArrayList<>();
list1.add(1);
//不带泛型的集合
List list2 = null;
//将带泛型的集合赋值给不带泛型的集合
list2 = list1;//此时泛型被擦除
list2.add("AA");
//带有String类型的泛型
List<String> list3 = null;
list3 = list2;
list3.add("Hello");
//Integer temp = list3.get(0);//用Integer接收list3中的第一个元素报错
String temp = list3.get(0);
//用String接收list3中的第一个元素,运行报错java.lang.Integer cannot be cast to java.lang.String
附堆污染