1 定义
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
2 特性
泛型类型在逻辑上可以看成是多个不同的类型,实际上都是相同的基本类型。
List<String> stringArrayList = new ArrayList<String>();
List<Integer> integerArrayList = new ArrayList<Integer>();
Class classStringArrayList = stringArrayList.getClass();
Class classIntegerArrayList = integerArrayList.getClass();
if(classStringArrayList.equals(classIntegerArrayList)){
Log.d("泛型测试","类型相同");
}
输出结果:类型相同
3 泛型使用
三种:泛型类,it 尬酒接口,泛型方法
3.1 泛型类
常见容器类:List,Set,Map等
注意:
泛型的类型参数只能是类类型,不能是简单类型(原始数据类型),比如,不能是 int,double,可以是 Integer,Double
2.不能对确切的泛型类型使用 instanceof 操作,编译就会出错,如:
if(a instanceof Class<String> ){}
3.2 泛型接口
public interface A<T>{
public T get();
}
当实现一个泛型接口的类,如果没传入泛型实数类型,则也要将泛型的场里一起加到类中。
class GenericClass<T> implements A<T>{
public T get(){
return null;
}
}
3.3 泛型通配符
我们知道,Integer 是 Number 的一个子类,那有一个问题,在 Func中,我们是否可以使用 Func的实例专入。
public void showValue(GenericClass<Number> fun){
Log.d("tag",fun.get());
}
GenericClass<Integer> funA = new GenericClass<Integer>(123);
GenericClass<Number> funB = new GenericClass<Number>(12345);
showValue(funA)
提示错误。
public void showValue(GenericClass<?> fun){
Log.d("tag",GenericClass.get());
}
此处,?是类型实参,而不是类型形参。也就是 ? 是所有类型的父类。是一种真实的类型
3.4 泛型方法
泛型类,是在实例化类的时候指明泛型的具体类型。泛型方法,是在调用方法的时候指明泛型的具体类型。
3.4.1 泛型方法的基本使用
public <T> T genericMethod(Class<T> cls) {
T t = cls.newInstance();
return t;
}
3.4.2 泛型方法在类中使用
public class GenericClass<T>{
public void show(T t){
}
/**
*,这里虽然使用了泛型 E,但是这个 E *也是一个泛型,也就是说,这个 E 也可以是任意类型,可以是 *T,也可以不是
**/
public <E> void show2(E e){
}
/**
*这里虽然使用了泛型 T,但是这个 T *也是一个泛型,也就是说,这个 T *也可以是任意类型,和泛型类中声明的 T不是同一种
**/
public <T> void show3(T e){
}
}
3.4.3 泛型方法与可变参数
public <T> void pringMsg(T... args){
}
3.4.4 静态方法与泛型
注意:静态方法无法访问类上定义的类型;如果静态方法操作的引用数据类型不确定时,必须将泛型定义在方法上.也就是说,静态方法要使用泛型的话,要将静态方法也定义成泛型方法.
publc static <T> void show(T t){
}
3.4.5 泛型方法总结
无论何时,如果你能做到,你就该尽量使用泛型方法。也就是说,如果使用泛型方法将整个类泛型化,那么就应该使用泛型方法。另外对于一个static的方法而已,无法访问泛型类型的参数。所以如果static方法要使用泛型能力,就必须使其成为泛型方法
3.5 泛型上下边界
泛型的上下边界添加,必须与泛型的声明在一起
public void showValue(Generic<? extends Number> obj){
}
public class GenericClass<T extends Number>{
}
public <T extends Number> showValue(Geniric<T> obj){
}
3.6 泛型数组
注:不能创建一个确切的泛型类型的数组
一个错误的例子:
List<String> [] ls = new ArrayList<String> [10]
但是可以使用通配符:
List<?> [] ls = new ArrayList<?>[10]
也可以是这样
List<String> [] ls = new ArrayList [10]
一个 Demo :
List<String>[] lsa = new List<String>[10]; // Not really allowed.
Object o = lsa;
Object[] oa = (Object[]) o;
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
oa[1] = li; // Unsound, but passes run time store check
String s = lsa[1].get(0); // Run-time error: ClassCastException.

被折叠的 条评论
为什么被折叠?



