一. 什么是泛型?

  • 泛型是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采用类型限定符前置。