一、总体认识
泛型.png二、重点说明
1.泛型擦除失去了代码的优雅性
import java.util.ArrayList;
import java.util.List;
public class 泛型擦除 {
public static String print(List<String> l){
System.out.println("");
return "";
}
/**
* 泛型擦除,导致这两个方法不能重载,因为泛型擦除后都成为了List<E>
* @param l
* @return
*/
public static int print(List<Integer> l){
System.out.println("");
return 1;
}
public static void main(String[] args){
// 在JDK1.6上通过修改两个方法的返回值可以达到上述两个方法重载的目的,
// 但JDK1.8上这样的处理方式编译器已经拒绝编译了
print(new ArrayList<String>());
print(new ArrayList<Integer>());
}
}
2.类型通配符、带限通配符
public class 泛型通配符 {
/**
* ?为通配符,它的元素类型可以匹配任何类型
* @param c
*/
public void test(List<?> c) {
for (int i = 0; i < c.size(); i++) {
System.out.println(c.get(i));
}
}
public static void main(String[] args) {
List<?> l=new ArrayList<String>();
/**
* 程序无法确定集合l中元素的类型,所以不能向其中添加对象。
* 故引入带限通配符:1,上限通配符;2,下限通配符
*/
// l.add("");
/**
* 1,上限通配符:
* 1)用extends:指定传入的类型必须是继承某个类;
* 2)实现某个接口:指定传入的类型必须实现某个接口
*/
// List<? extends Shape> l1=new ArrayList<Circle>();
/**
* 2,下限通配符
* 1)用super:指定传入的类型必须是某个类的父类,或某个接口的父接口,
* 也可以是这个类或接口本身
*/
// List<? super Circle> l2=new ArrayList<Shape>();
}
}
3.泛型擦除
不管传入哪一种类型实参,Java都把它们当做同一个类型进行处理。故Java泛型这一概念只作用于代码编译阶段,在编译过程中正确检验泛型结果后,会将泛型的相关信息擦除。泛型信息不会进入到运行时阶段。
/**
*
* <p>Description:
* 泛型擦除:无论泛型实参是什么,Java都把他们当成同一个类型进行处理。
* </p>
* @author 杨丽金
* @date 2018-4-19
* @version 1.0
*/
public class 证明泛型擦除 {
public static void main(String[] args) {
// 定义两个集合类型的变量,分别传入不同的实参,判断他们的类型是否相同
List<String> l1=new ArrayList<>();
List<Integer> l2=new ArrayList<>();
System.out.println(l1.getClass()==l2.getClass());// true
}
}
网友评论