什么是泛型
是JDK5引入的一个新特性,泛型的本质就是类型参数化,比如我们创建一个ArrayList集合存数据,就是ArrayList<String> list=new ArrayList<String>();String的位置就是参数的位置,使用泛型把类型参数化,等到我们在使用的时候再给他一个具体的值,让他存String类型的数据。泛型也是一种语法糖,基本原理就是类型擦除。
语法糖(Syntactic sugar),也译为糖衣语法,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
泛型的好处
避免了许多强制类型转换,保证了类型安全
泛型的主要目的就是提高java程序的类型安全,比如我们是用数组列表的时候,如果没有泛型,每次取出数据都需要强制类型转换,因为不知道存进去的是什么类型,而且在编译的时候编译器不知道类型转换是否正常,运行时才知道,非常不安全。而有了泛型之后,编译时期就可以检查出来因为类型不符而导致的错误。
publicstaticvoidmain(String[] args) {
//不使用泛型
ArrayListlist=newArrayList();
//使用泛型,就不会允许放进去不同类型的数据
//ArrayList<String> list=new ArrayList();
list.add("你好");
list.add(666);
//运行后会出现 强制类型转换异常 ClassCastException
Stringstring=(String) list.get(0);
Stringnum=(String) list.get(1);
}
2、泛型的所有工作都在编译器中完成,所以只存在于编译阶段,不存在于运行阶段,编译器生成的代码跟不使用泛型的时候几乎是一模一样的,只不过泛型能确保类型安全,JVM进行类编译的时候会进行检查,如果一个集合被定义为String类型,那么它向集合里存取数据的时候就会对数据判断,避免存入或取出错误的数据。
ArrayList<String>a=newArrayList<String>();
ArrayList<Integer>b=newArrayList<Integer>();
Classc1=a.getClass();//返回Class类型的对象
Classc2=b.getClass();
System.out.println(c1==c2);//输出结果是true,发现他们的Class类型是一致的,都是
//ArrayList.class
泛型中的限定通配符和非限定通配符
限定通配符对类型进行了限制,有两种限定通配符,一种是<? extends T>它通过确保类型必须是T的子类来设定类型的上限;另一种是<? super T>它通过确保类型必须是T的父类来设定类型的下界。泛型类型必须用限定内的类型来进行初始化,否则会导致编译错误。
非限定通配符可以用任意类型代替:比如List<?>的意思就是这个集合可以存任何类型。
类型擦除:
简单来说就是使用泛型的时候加上类型参数,编译器在编译的时候会去掉类型参数。泛型实现的内部原理就是类型擦除,比如说我们在list集合中存一个Integer类型的数据(list.add(10)),java编译的时候编译器会擦除尖括号,将Integer类型定义为Object类型,我们往外拿数据的时候(list.get(0)),编译器还会做一个类型转换。如果接受的类型是int的话,还会做一个自动拆箱的操作。