---------------------- android培训,java培训、期待与您交流! ----------------------
泛型:
(以下总结部分参考自 java核心技术)
简单概括:
泛型也是jdk1.5的新特性,它是模仿C++的泛型产生的,它的出现实现了一份代码可以被多种不同类型的对象重用,并且是代码简单,安全.
泛型只在编译时期有效,通过泛型,编译器可以过滤一些不符合泛型的类型,而jvm在执行程序的时候,会去掉泛型,
泛型中的专业术语:
ArrayList<E>类定义和ArrayList<Integer>类引用中的术语:
1. 这个称谓ArrayList<E>泛型类型
2. 整个ArrayList<E>中的E称为类型变量或类型参数
3. 整个ArrayList<Integer>称为参数化类型
4. ArrayList<Integer>中的Integer称谓类型参数的实例或者实际类型参数
5. ArrayList<Integer>中的<>念typeof
6. ArrayList称为原始类型
关于泛型的简单性和安全性用一个简单的例子来感性的了解一下:
在没有出现泛型的时候,要实现一份代码被多种类型的对象重用,需要把类型定义为Object:
class Demo
{
public Object get(int i){...};
publicvoid add(Object []obj){};
...
}
这样实现存在两个问题
1. 当获取一个值的时候必须进行强制类型转换,而要转换成什么类型,必须是开发者知道的,如果转换错误,编译器也不会错误提示,而是在运行时出错,这样就出现了安全隐患
2. 在给add放传递参数的时候,由于接收的参数类型是Object数组,所以可以往数组里添加任何类型的对象,而数组只能存放一种数据类型,这样也会出现安全隐患
泛型的出现提供了一个很好的解决方案:类型参数. 什么是类型参数? 类型参数就是把类型作为一个参数传入,这样就能提高代码的安全性
例如: Demo <String> demo= new Demo<String>();
尖括号里面的就是泛型,定义这个泛型就是在告诉编译器,这个对象里面只能放String类型的数据,这么一来,就不用再进行强制类型转换了,并且编译器会自动过滤传入的参数的类型,如果不满足泛型定义好的类型,编译器是不会编译通过的,这样就把运行时错误转换成了编译时错误.所以泛型的出现提高了代码的简易性和安全性
泛型可以定义在类,方法,变量上,但是泛型的类型只能是引用数据类型,不能是基本类型
自定义泛型:
泛型不仅可以指定某种类型作为类型参数,也能自定义类型.
自定义泛型可以在定义泛型类,泛型方法等的时候用一个<T>(T仅是一个名字,可以任意)来表示一个类型参数,然后在使用到这个泛型类型的时候再动态的传入参数,传入的参数是什么类型,T就代表什么类型
通配符泛型:
如果需要得到任意类型的参数化类型,那么这时,<>里面就不能放Integer等单一的类型了,但是泛型不支持继承关系,所以不能放Object,那么这要怎么做呢?这时可以使用通配符?
使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要作用是引用,可以调用与参数化无关的方法,但是不能调用与参数化有关的方法.
通配符泛型和自定义泛型的区别:
1. 通配符泛型相当于一个占位符,具体类型可以是任意; 自定义泛型的具体类型是由外界传入的数据的类型决定的,一旦决定就确定了.
2. 通配符泛型不能操作与类型相关的方法,因为它的类型不确定; 自定义泛型不能操作与类型相关的方法,因为它的类型是确定的.
3. 通配符泛型可以向上限定也可以向下限定;自定义泛型只能向上限定
类型参数的类型推断:
根据调用泛型方法时实际传递的参数类型或返回值的类型来判断,具体规则如下:
1. 当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用,那么根据调用方法时的实际应用类型来确定.
如:swap(new String[3],3,5) à static<E> void swap(E[] a, int I,int j)
2. 当某个类型变量在整个参数列表中的所有参数和返回值中多处被应用,如果调用方法时这多处的实际应用类型都对应同一种类型来确定.
如:add(2,3) à static<T> T add(T a , T b)
3. 当某个类型变量在整个参数列表中所有参数和返回值中多处被应用,如果调用方法时这多处的实际应用类型对应到不同的类型,且没有使用返回值,这时取多个参数中的最大交集类型,例如,下面语句实际对应的类型就是Number.
例如: fill(new Integer[3], 3.5f ) à static <T> void fill(T[] a ,T b)
泛型方法:
例: public <T> T demo(){}
方法的返回值被定义成泛型,类型变量放在修饰符的后面,返回类型的前面,泛型方法可以定义在泛型类中,也可以定义在普通类中,当调用一个泛型方法的时候,在方法名前面的尖括号中放入具体的类型
用反射得到泛型的实际参数:
当定义一个泛型ArrayList<String>,我们要怎么得到这个泛型的实际参数呢?
普通的方法是不能得到的,要得到这个实际参数,需要把这个类型传入一个方法,然后通过反射的方式得到这个方法,然后通过方法中的getActualTypeArguments方法来得到参数类型
---------------------- android培训,java培训、期待与您交流! ----------------------
详细请查看http://edu.youkuaiyun.com/heima