java泛型

泛型之前

在面向对象编程语言中,多态算是一种泛化机制。例如,你可以将方法的参数类型设置为基类,那么该方法就可以接受从这个基类中导出的任何类作为参数,这样的方法将会更具有通用性。此外,如果将方法参数声明为接口,将会更加灵活。

在Java增加泛型类型之前,通用程序的设计就是利用继承实现的,例如,ArrayList类只维护一个Object引用的数组,Object为所有类基类。

publicclassBeforeGeneric {
staticclassArrayList{//泛型之前的通用程序设计private Object[] elements=new Object[0];
public Objectget(int i){
return elements[i];
		}
publicvoidadd(Object o){
//这里的实现,只是为了演示,不具有任何参考价值int length=elements.length;
			Object[] newElments=new Object[length+1];
for(int i=0;i<length;i++){
				newElments[i]=elements[i];
			}
			newElments[length]=o;
			elements=newElments;
		}
	}
publicstaticvoidmain(String[] args) {
		ArrayList stringValues=new ArrayList();
		stringValues.add(1);//可以向数组中添加任何类型的对象//问题1——获取值时必须强制转换
		String str=(String) stringValues.get(0);
//问题2——上述强制转型编译时不会出错,而运行时报异常java.lang.ClassCastException
	}
}

这样的实现面临两个问题:

1、当我们获取一个值的时候,必须进行强制类型转换。

2、假定我们预想的是利用stringValues来存放String集合,因为ArrayList只是维护一个Object引用的数组,我们无法阻止将Integer类型(Object子类)的数据加入stringValues。然而,当我们使用数据的时候,需要将获取的Object对象转换为我们期望的类型(String),如果向集合中添加了非预期的类型(如Integer),编译时我们不会收到任何的错误提示。但当我们运行程序时却会报异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at generic.BeforeGeneric.main(BeforeGeneric.java:24)

这显然不是我们所期望的,如果程序有潜在的错误,我们更期望在编译时被告知错误,而不是在运行时报异常。

泛型

针对利用继承来实现通用程序设计所产生的问题,泛型提供了更好的解决方案:类型参数。例如,ArrayList类用一个类型参数来指出元素的类型。

ArrayList<String> stringValues=new ArrayList<String>();

这样的代码具有更好的可读性,我们一看就知道该集合用来保存String类型的对象,而不是仅仅依赖变量名称来暗示我们期望的类型。

publicclassGenericType {
publicstaticvoidmain(String[] args) {
		ArrayList<String> stringValues=new ArrayList<String>();
		stringValues.add("str");
		stringValues.add(1);//编译错误
	}
}

现在,如果我们向ArrayList<String>添加Integer类型的对象,将会出现编译错误。 Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method add(int, String) in the type ArrayList<String> is not applicable for the arguments (int) at generic.GenericType.main(GenericType.java:8)

编译器会自动帮我们检查,避免向集合中插入错误类型的对象,从而使得程序具有更好的安全性。

总之,泛型通过类型参数使得我们的程序具有更好的可读性和安全性。

Java泛型的实现原理

擦除