一. 什么是泛型?
- 泛型是1.5引入的类型机制。就是将参数类型化。
- 泛型机制将类型转换时的类型检查从运行时提前到编译时,使用泛型编写的丹麦比杂乱的使用object并在需要时再强调类型转换的机制具有更好的可读性和安全性。
- 泛型程序设计意味着程序可以被不同类型的对象重用。
- 泛型对集合类尤为有用。如ArrayList,在没有泛型之前采用继承机制实现的,实际上它只维护了一个object对象的数组,结果就是对list来说它只操作了一类对象Object,而在用户看来却可以保持不同的对象。
- 泛型对参数类型提供了更好的解决办法。
List<String> list=new ArrayList<String>();
- 这样就解决了以下几个问题:
1.可读性。从字面上就可以判断集合中的内容类型。
2.类型检查。避免插入非法类型。
3.获取数据室不再需要类型强制转换。
二、泛型类
public class Info<T>{
private T field;
}
- 其中就是类型参数定义。
- 使用时:
Info<String> p=new Info<String>();
此时类内部的field就是字符串类型了。 - 如果引用多喝类型,可以用都好分隔:
<S,D>
- 类型参数名可以使用任意字符串,建议使用由代表意义的单个字符,以便于和普通类型名区分,如:T代表着type,有原数据和目的数据就用S,D,子元素类型用E等,也可以自己定义,但是为了规范,务必采用默认的字符。
三、泛型方法
泛型方法定义如下:
public static <T> T marshlle(T arg){}
和泛型一样,<T>
是类型参数定义。如:
public class DemoMethod{
public static <T> T getMiddle(T... a){
return a[a.length/2];//参数为多个时,a表示为参数组成的数组,此时返回的是多个参数中的中间参数
}
}
严格的调用方式:
String str=DemoMethod.<String> getMiddle("13","result","12");
一般情况下,调用时可以省略,看起来就像定义String类型输出的方法:
String str=DemoMethod.getMiddle(String str1,String str2,String str3);
这是因为jdk会根据参数类型进行推断,推断为String。
但是参数类型不同的情况下,如例(“result”变为0):
Object o=DemoMethod.getMiddle("13",0,"12");
System.out.println(o.getClass());
System.out.println(o);
输出结果为:
class java.lang.Integer
0
这是因为jdk推断三个参数的共同父类,匹配为Object,那么相当于:
Object o=DemoMethod.<Object> getMiddle("13",0,"12");
习惯了类型参数放在类的后面,如ArrayList<String>
,泛型方法为什么不放在后面?
如:
public class DemoMethod {
public static <T,S>T f(T t){return t;}
public static class A{}
public static class B{}
@Test
public void test(){
DemoMethod demo=new DemoMethod();
A a=new A();
demo.<A,B>f (a);//OK
demo.f<A,B>(a);//erroe看起来像是一个逗号运算符连接的两个逻辑表达式,当然目前java中除了for(...)并不支持逗号运算符
}
}
因此,为了避免歧义,jdk采用类型限定符前置。