标签:匹配 eric integer 运算 image aik 运行 质量 可见
泛型
1.什么是泛型
2.泛型类、泛型接口、泛型方法
3.为什么要使用泛型,泛型的好处
4.使用泛型注意点
5.泛型擦除
1.什么是泛型
1.1泛型概念:Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter),
这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
1.2本质:参数化类型
1.3语法:<T>, T 称为类型占位符,表示一种引用类型。
1.4特点:(1)编译时即可检查,非运行时抛出异常;
(2)访问时不需要类型转换(拆箱);
(3)不同泛型之间不能相互赋值,泛型不存在多态。
对于泛型特点(1)举个例子 : 没有使用泛型时的异常抛出
public class MyGenericTest { public static void main(String[] args) { List list = new ArrayList(); list.add(123); //添加Integer对象 list.add("zifu"); //添加String对象 list.add(1.22); //添加Double对象 for(Object object: list) { //!!!使用,例如要进行运算使用 Double num = (Double)object; System.out.println(num); } } }
结果:Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double
at MyGenerics.MyGenericTest.main(MyGenericTest.java:28)
分析一下:编译通过,但是运行提示异常,类型转换异常,就是String类型不能转换为Double类型。我们在使用 list.add() 方法时,根据提示知道凡是Object对象都可以添加进去,但是要使用的时候忘了添加过什么类型的对象进去,根据提示强转过,但是由于添加进去一些类型不同的,强转可以在编译时通过,运行时异常抛出了。
这里就可以体现泛型的好处之一了:防止类型转换异常,提高代码的安全性。
对于泛型特点(2)访问时不需要类型转换(拆箱),举例子List<String> list = new ArrayList<String>();
查看ArrayList的访问4方法get()源码,看到返回值类型是泛型E,所以我们获取时就不用强转了。
package MyGenerics; import java.util.ArrayList; import java.util.List; public class MyGenericTest { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("dingdong"); list.add("zifu"); list.add("meimei"); for(int i = 0; i < list.size(); i++) { //!!!使用 String str = list.get(i); //访问时不需要类型转换 System.out.println(str); } } }
对于泛型特点(3)不同泛型之间不能相互赋值,举例
对于泛型特点(3)泛型不存在多态,举例
另外这里报错原因是:Type mismatch: cannot convert from ArrayList<Integer> to ArrayList<Number>,类型不匹配的愿意
2.泛型类、泛型接口、泛型方法
2.1泛型类
语法:类名<T,........>
举例:
package MyGenerics; import java.util.List; //Generic类,泛型类 //语法:类名<T> public class MyGeneric <T>{ //添加属性(泛型属性变量) T t; //添加方法(泛型参数) public void show(T t) { System.out.println(t); } //添加方法(泛型做为返回值) public T getT() { return t; } }
2.2泛型接口与泛型类相似,不举例子了
语法:接口名<T, .......>
2.3泛型方法
语法:[ 修饰符] <T> 返回值类型 方法名([参数列表])
2.4.疑惑,为什么有泛型类了,还要有泛型方法,泛型类与泛型方法有什么区别,泛型方法有什么好处?
为什么要使用泛型方法呢?(想换类型时,考虑方法的调用方便的好处,而类需要实例化)
因为泛型类要在实例化的时候就指明类型,如果想换一种类型,不得不重新new一次,可能不够灵活;而泛型方法可以在调用的时候指明类型,更加灵活。
3.为什么要使用泛型,泛型的好处:
3.1泛型的好处
答:提高代码重用性,防止类型转换异常,提高代码的安全性。(也可以加上泛型特点(1)(2))
3.2泛型类的好处
答:使用泛型类可以解决重复业务的代码的复用问题,也就是业务颗粒的复用,同时使用泛型类型在编译阶段就可以确定,并发现错误,类型的转换都是自动和隐式的,提高了代码的准确率和复用率。
4.使用泛型注意点:
4.1不同泛型之间不能相互赋值,泛型不存在多态((检查机制)泛型特点(3))
4.2要注意泛型擦除
5.泛型擦除
5.1 泛型擦除概念: 类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法。
简单理解:在编译期间,所有的泛型信息都会被擦除掉。例如代码中定义的List<Object>和List<String>等类型,在编译后都会变成List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。
5.2 由于泛型擦除出现的错误举例:
报错原因:Erasure of method MyGeneric(ArrayList<String>) is the same as another method in type MyGeneric<T>,
Erasure of method MyGeneric(ArrayList<Integer>) is the same as another method in type MyGeneric<T>
类型擦除的原因,擦除后 //方法重载,都变成了
public MyGeneric(ArrayList arrayList) {
}
完美解释此处问题,但是却勾起小伙伴的另外一个问题,类型擦除了,为什么不同泛型之间不能相互赋值!!
因为检查机制的存在,编译器的工作是这样子滴:首先进行类型检查,检查类型不同,报错!如果类型相同,再进行类型擦除啦!!!(即进入擦除阶段,需要通过检查那一关)
举个例子,购买的衣服,需要相关人员先进行质量合格等方面的检查,检查通过,进入商城,消费者购买完撕掉了吊牌。。。。。
标签:匹配 eric integer 运算 image aik 运行 质量 可见
原文地址:https://www.cnblogs.com/shan333/p/14462986.html