- 先说明一下擦除的原理。在java中,允许吧带有泛型的变量赋值给不带泛型信息的变量,但是一旦这样做的话,所有关于方形的信息就会丢失,比如把List<String>赋值给List的话,泛型信息<String>就会丢失,也就是说List中所有集合元素的类型都是Object了。
- 以下是第一个代码示例,本来a是带有泛型信息,但是b没有,所以在赋值过程中泛型信息就丢失了,b中的T的类型会变成其上限Number,就是因为这样,最后一行会发出报错信息。
//一下代码中,当把一个带泛型信息的a的实例赋值给一个不带泛型信息的的b的时候, //a中所有的泛型信息都会发生丢失,也就是说T是Integer的这一信息会丢失,b只知道 //T的类型是Number而已 package ErasureAndConversion; import UseIt.A1; class Apple<T extends Number>{ T size; public Apple(){ } public Apple(T size){ this.size = size; } public void setSize(T size){ this.size = size; } public T getSize(){ return this.size; } } public class Erasure { public static void main(String args[]){ Apple<Integer> a = new Apple<>(6); // a指向的实例是带有泛型信息的 Integer as = a.getSize(); // 实例a中的T是Integer类型的,所以赋值给as没有任何问题 Apple b = a; // 这一句就是说明问题的关键了,b是不带泛型信息的,所以a中的泛型信息 // 也就会被擦除,所以,a中的T的类型就只是Number而已了 Number size1 = b.getSize(); // b中的T类型是Number,所以赋值给Number类型的值没有任何问题 // Integer size2 = b.getSize(); // 但是,b中的T并不是Integer的了,因为泛型信息已经被擦除了,所以这一句会 // 报错。 Integer size3 = a.getSize(); // 另外补充一点,最后这一句并不会报错,b会发生泛型信息丢失但是a并不会受影响 } }
-
下面这两个例子说明的是一样的问题,或者说第三个例子是第二个例子的直观表现,说的是当把带有泛型信息的集合赋值给没有泛型信息的集合时泛型信息就丢失了,所以在把list赋值给ls的时候不会发生问题,因为list已经不知道具体的泛型信息是什么了,所以是Object,所以可以赋值给ls,但是一旦要访问集合中的元素的时候,就会发生类型不匹配的问题。
//java允许把一个List赋值给一个List<Type>所以在下面 List<String> ls = list; //这一句仅仅只会发生警告而已。 package ErasureAndConversion; import java.util.ArrayList; import java.util.List; public class Erasure2 { public static void main(String args[]){ List<Integer> li = new ArrayList<>(); li.add(6); li.add(5); List list = li; List<String> ls = list; // 一样的道理,List没有泛型信息,所以li的泛型信息就丢失了,所以赋值给ls // 是没有问题的 // System.out.println(ls.get(0)); // 但是当访问ls中的元素的时候,就会发生类型不匹配的问题 } }
//这个例子和上面的例子是一模一样的 package ErasureAndConversion; import java.util.ArrayList; import java.util.List; public class Erasure3 { public static void main(String args[]){ List list = new ArrayList(); ((ArrayList) list).add(5); ((ArrayList) list).add(4); // System.out.println((String)list.get(0)); } }
java泛型(5) 擦除与转换
最新推荐文章于 2022-08-09 10:43:33 发布