泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。
一、泛型的概述
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?
顾名思义,就是将原来具体的类型参数化,类似于方法中的参数, 然后在使用/调用时传入具体的类型(类型实参),Java中将类型也定义成参数形式的概念就叫做泛型。
泛型的作用是为了参数化类型,在不创建新的类型的情况下,通过泛型指定的不同类型来达到:一次定义,多个用途。
泛型这种概念可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
Java中常用来表示泛型的通配符:
`T :代表一般的任何类。`
`E :代表 Element 元素的意思,或者 Exception 异常的意思。`
`K :代表 Key 的意思。`
`V :代表 Value 的意思,通常与 K 一起配合使用。`
`S :代表 Subtype 的意思
(一)、泛型类
public class Generic<T> { // key 这个成员变量的数据类型为 T, T 的类型由外部传入 private T key; // 泛型构造方法形参 key 的类型也为 T,T 的类型由外部传入 public Generic(T key) { this.key = key; } // 泛型方法 getKey 的返回值类型为 T,T 的类型由外部指定 public T getKey(){ return key; } }
①在泛型类中,类型参数定义的位置有三处,分别为:
1.非静态的成员属性类型
2.非静态方法的形参类型(包括非静态成员方法和构造器)
3.非静态的成员方法的返回值类型
注意点:
1.泛型类中的静态方法和静态变量不可以使用泛型类所声明的类型参数(T)
(也就是对于静态的东西,不可以使用泛型,必须在初始化时就确定其具体类型)
2.泛型类中的类型参数(T)是在创建泛型类实例的时候确定的。
(例如 ArrayList< Integer >
)。
3.在创建泛型类的对象时,必须指定类型参数 T 的具体数据类型,如果 <> 中什么都不传入,则默认是 < Object >
。
②泛型类不只接受一个类型参数,它还可以接受多个类型参数。
public class MultiType <E,T> { E value1; T value2; public E getValue1(){ return value1; } public T getValue2(){ return value2; } }
(二)、泛型方法
1. 泛型方法的定义
当在一个方法签名中的返回值前面声明了一个 < T > 时,该方法就被声明为一个泛型方法。< T >表明该方法声明了一个类型参数 T,并且这个类型参数 T 只能在该方法中使用。当然,泛型方法中也可以使用泛型类中定义的泛型参数。
public <类型参数> 返回类型 方法名(类型参数 变量名) { ... }
注意点:
1.有在方法签名中声明了< T >的方法才是泛型方法,仅使用了泛型类定义的类型参数的方法并不是泛型方法。
public class Test<U> { // 该方法只是使用了泛型类定义的类型参数,不是泛型方法 public void testMethod(U u){ System.out.println(u); } // <T> 真正声明了下面的方法是一个泛型方法 public <T> T testMethod1(T t){ return t; } }
2.泛型方法中可以同时声明多个类型参数。
public class TestMethod<U> { public <T, S> T testMethod(T t, S s) { return null; } }
3.泛型方法中也可以使用泛型类中定义的泛型参数。
public class TestMethod<U> { public <T> U testMethod(T t, U u) { return u; } }
4.特别注意的是:泛型类中定义的类型参数和泛型方法中定义的类型参数是相互独立的,它们一点关系都没有.
public class Test<T> { public void testMethod(T t) { System.out.println(t); } public <T> T testMethod1(T t) { return t; } }
上示代码中,Test<T> 是泛型类,testMethod() 是泛型类中的普通方法,其使用的类型参数是与泛型类中定义的类型参数相同。
而 testMethod1() 是一个泛型方法,他使用的类型参数是与方法签名中声明的类型参数。
虽然上述泛型类中定义的类型参数标识和泛型方法中定义的类型参数标识都为<T>,但它们彼此之间是相互独立的。也就是说,泛型方法始终以自己声明的类型参数为准。