java泛型II-泛型中存在的约束与局限性

java泛型中存在一定的约束和局限性,这些限制的主要原因是java虚拟机中对泛型的处理机制有关,即类型擦除
1:不能用基本类型实例化类型参数
主要原因就是:类型擦除引起的,ArrayList会被转为Object,但double没有继承object。
如:
ArrayList<Double> list=new ArrayList<>();//正确 ArrayList<double> list=new ArrayList<>();//错误
2:运行时类型查询只适合用于原始类型

public class test2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ArrayList<String> list=new ArrayList<>();
		ArrayList<Integer> list2=new ArrayList<>();
System.out.println(list.getClass()==list2.getClass());
System.out.println(list.getClass().getName());
	}
}

运行结果:

true
java.util.ArrayList

通过运行结果发现:
两次调用的getClass都返回的java.util.ArrayList,因此在泛型中类型查询返回的是泛型的原始类型。
3:不能创建参数化类型的数组

public static void main(String[] args) {
		// TODO Auto-generated method stub
		Pair<String> [] array=new Pair<String>[10];

	}

运行结果:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Cannot create a generic array of Pair<String>

	at com.csu.fanxing.test2.main(test2.java:9)

结果分析:由于array经过虚拟机擦除后,array类型是Pair[],所以假设改数组能够初始化成功,那存储时依然会出现问题。
4:不能实例化类型变量

public class Pair<T> {
	private T first;
	private T second;
	public T getFirst() {
		return first;
	}
	public Pair()
	{
		first=new T();
		second=null;
	}

报错:first=new T();Cannot instantiate the type T。无法实例化类型T。所以不能用像new T(),new T[...]等这样的表达式实例化类型变量。
5:泛型类的静态上下文中类型变量无效

public class Singleton <T>{
	private static T singleInstance;//错误
	public static T getInstance()//错误
	{
		//dosomething
	}
}

编译不通过的主要原因是泛型擦除后,只有Singleton,如果声明一个Singleton和一个Singleton,那么就会出现程序混乱。因为泛型类中的泛型参数的实例化是在定义对象的时候指定的,而静态变量和静态方法不需要使用对象来调用。对象都没有创建,如何确定这个泛型参数是何种类型,所以当然是错误的。

public static<T> T getInstance(T a)//错误
	{
		//dosomething
	}

注意:这个是正确的,因为它是泛型方法,它使用的T是自己在方法中定义的T,而不是泛型类中的T。
6:类型擦除后的冲突
当泛型类型被擦除后,创建条件不能产生冲突。如果在Pair类中添加下面的equals方法:

class Pair<T>   {
	public boolean equals(T value) {
		return null;
	}	
}

考虑一个Pair。从概念上,它有两个equals方法:

booleanequals(String); //在Pair<T>中定义
boolean equals(Object); //从object中继承

但是,这只是一种错觉。实际上,擦除后方法
boolean equals(T)变成了方法 boolean equals(Object),这与Object.equals方法是冲突的!当然,补救的办法是重新命名引发错误的方法。
7:泛型类型的继承规则
这里写图片描述
从图可以看出,B与BSub之间是集成关系,但在ArrayList与ArrayList没有任何关系。
但是特别注意:ArrayList与List之间有关系,由于ArrayList实现的是List接口。

原文地址:https://www.cnblogs.com/csuwater/p/5398853.html