泛型类及应用
在使用泛型定义的类创建对象时,即在泛型实例化时,可以根据不同的需求给出类型参数T的具体类型。而在调用泛型类的方法传递或返回数据类型时可以不用进行类型转换,而是直接用T作为类型来代替参数类型或返值的类型。
说明:在实例化泛型类的过程中,实际类型必须是引用类型,即必须是类类型,不能用如int、double或char等这样的基本类型来替换类型参数T。
例题:泛型类的定义及应用
//filename:App12_1.java 泛型类的应用
public class App12_1 <T> //定义泛型类,T是类型参数
{
private T obj; //定义泛型类的成员变量
public T getobj() //定义泛型类的方Name法
{
return obj;
}
public void setObj(T obj) //定义泛型类的方法 setObj()
{
this.obj=obj;
}
public static void main(String[] args)
{
App12_1<String>name =new App12_1<String>();//创建App12_1<String>型对象
App12_1<Integer> age= new App12_1<Integer>();//创建App12_1<Integer>型对象
name.setObj("陈 磊");
String newName=name.getobj();
System.out.println("姓名:"+newName);
age.setObj(25); //Java自动将25包装为new Integer(25)
int newAge=age.getobj();//Java将Integer类型自动解包成int类型
System.out.println("年龄:"+newAge);
}
}
程序运行结果如下:
姓名:张磊
年龄:25
通过该例可以看出,泛型类的定义并不复杂,可以将T看作是一种特殊的变量,该变量的“值”在创建泛型对象时指定,它可以是除了基本类型之外的任意类型,包括类、接口等引用类型。
说明:当一个泛型有多个类型参数时,每个类型参数在该泛型中都应该是唯一的。如不能定义形如Map<K,K>形式的泛型,但可以定义Map<K,V>形式的泛型。
泛型方法
一个方法是否是泛型方法与其所在的类是否是泛型类没有关系。要定义泛型方法,只需将泛型的类型参数<T>置于方法返回值类型前即可。在Java中任何方法(包括静态方法和构造方法)都可声明为泛型方法。泛型方法除了定义不同,调用时与普通方法一样。
例题:泛型方法的应用
//filename:App12_2.java
public class App12_2
{
public static void main(String[] args)
{
Integer[] num= {1,2,3,4,5};
String [] str= {"红","橙","黄","绿","青","蓝","紫"};
App12_2.display(num);
App12_2.display(str);
}
public static <E> void display(E[] list)
{
for(int i=0;i<list.length;i++)
System.out.print(list[i]+" ");
System.out.println();
}
}
该程序运行结果如下:
1 2 3 4 5
红 橙 黄 绿 青 蓝 紫
一般来说编写Java泛型方法时,返回值类型和至少一个参数类型应该是泛型,而且类型应该是一致的,如果只有返回值类型或参数类型之一使用了泛型,这个泛型方法的使用就大大地受限制,基本限制到跟不用泛型一样的程度。所以推荐使用返回值类型和参数类型一致的泛型方法。Java泛型方法广泛使用在方法返回值和参数均是容器类对象的情况。
- 注意:若泛型方法的多个形式参数使用了相同的类型参数,并且对应的多个类型实参具有不同的类型,则编译器会将该类型参数指定为这多个类型实参所具有的“最近”共同父类直至Object。
- 说明:一个static方法,无法访问泛型类的类型参数,所以如果static方法需要使用泛型能力,必须使其成为泛型方法。
当使用泛型类时,必须在创建泛型对象的时候指定类型参数的实际值,而调用泛型方法时,通常不必指明参数的类型,因为编译器有个功能为类型参数推断,此时编译器会找出具体的类型。类型推断只对赋值操作有效,其他时候并不起作用。