为什么要使用泛型?

  • 我们在学习完ArrayList容器之后,发现ArrayList里面能够放各种的东西,他可以add(),get(),并且在声名构造一个数组列表的时候用<>来说明这个容器里面放的是什么类型的东西,可在这之前的Java版本中并没有<>,只有一个叫做ArrayList的类,,其中保存类型为Object的元素,我们在实例化的时候总要进行强制类型转换,这使得我们在有些转换中会出现错误,而只有随着Java的发展有一个更好的解决办法就是泛型,一种叫做类型参数(type parameters)的东西来帮我们指示元素的类型。

  • 并且要记住的是定义的泛型的一切东西仅仅存在于编译阶段在运行之后,相应的泛型会被擦除。

ArrayList a=new ArrayList();
String aName =(String) files.get(0);

变成:

ArrayList<String> a=new ArrayList<String>;

这样子使得我们简便了许多,这个带着<String>的这行代码是说定义一个只能放String类型的名字叫做a的容器。 

 

如何定义简单泛型类?

package generic;

public class Pair<T> { //T is type parameters
	private T first;
	private T second;
	public Pair() {  //constructed function
		first=null;
		this.second=second;
	}
	public Pair(T first,T second) {    //constructed function
		this.first=first;
		this.second=second;
	}
	
	public T getFirst() {   //泛型类中的普通方法,下面都一样
		return first;
	}
	public T getSecond() {
		return second;
	}
	
	public void setFirst(T newValue) {
		first=newValue;
	}
	public void setSecond(T newValue) {
		second=newValue;
	}
	
}

这样我们就定义了一个T类型的泛型类叫做Pair,我们一般用T来表示任意未知类型,

 

如何使用泛型类?

package generic;

public class PairTest1 {
	public  Pair<Integer> minmax(int[] a)    
	{
		int min=a[0];
		int max=a[0];
		for(int i=1;i<a.length;i++) {
			if(min>a[i]) min=a[i];
			if(max<a[i]) max=a[i];
		}
		return new Pair<>(min,max);    //返回一个Pair<Integer>类型
	}
	public static void main(String[] args) {
		int[] a= {2,6,7,10,0};
		PairTest1 b=new PairTest1();
		Pair<Integer> bb=b.minmax(a);
		System.out.println("min= "+bb.getFirst());
		System.out.println("max= "+bb.getSecond());
		
}
	
}

 

定义一个泛型方法:

public <T> T min(T a){
    
    return T;

 <T> 是声名这是个T的泛型类型 min前面这个T指的是返回类型,(T a)指的是传入的参数

示范一下如何使用: 

package generic;

public class MethodTest {
	String apple="apple";
	int b=0;
	public <T> T GetValue(T a) {
		return a;
	}
	public static void main(String[] args) {
		MethodTest t=new MethodTest();
		System.out.println(t.<Integer>GetValue(t.b));
		System.out.println(t.<String>GetValue(t.apple));
	}

}

我的理解是: 在我们对不同类型的东西进行相同操作时,我们需要定义不同类型的函数,非                        常的繁琐,这时候我们就需要使用泛型方法了,它可以对不同类型的值进行                            操作

注意:不是泛型类中的方法就是泛型方法,很有可能是泛型类中的成员方法!

          必须是按照一定的定义规则定义出的方法才是泛型方法!

 

关于对类型变量的限定:

下面的代码可以对方法或者类进行限定

public <T extends Comparable> T min(T[] a) ...

就是说这个min方法只能被实现了Comparable的类的数组调用

一个类型变量可以有多个限定:

T extends Comparable & Serializable

限定类型之间用“&”分隔,而逗号来分隔变量 

可以根据需要限定多个接口类型,但是限定中之多有一个类,若果用类来限定,它必须是限定列表中的第一个

注意:虚拟机没有泛型类对象——所有对象都属于普通类: 

      无论何时定义一个泛型类,都自动提供一个相应的原始类型,原始类型的名字就是删去类        型参数后的泛型类型名,擦除(erased)类型变量,并替换为限定类型

 

最后的关于泛型的约束与局限性

   不能用基本类型实例化类型参数

   运行时类型查询只适用于原始类型(会被编译器警告)

   不能创建参数化类型的数组(只能声名,不能new):

Pair<String>[] table=new Pair<String>[10];//错的!

     因为在运行时会被类型擦除Pair[]---->Object[]存入其他类型是会抛出异常        

 

以上

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐