下面将阐述使用java泛型时需要考虑的一些限制。大多数限制都是由类型擦除引起来。
1.不能用类型参数代替基本类型。
因此没有Pair<double>
只有Pair<Double>
;
2.运行时类型查询只适用于原始类型
虚拟机的对象总有一个特定的非泛型类型.
//所有的类型查询值产生原始类型
Pair<String> a = ...;
if(a instanceof Pair<String>)//error
if(a instanceof Pair<T>)//error
//getClass方法总是返回原始类型
Pair<Employee> b = ...;
if(a.getClass() == b.getClass()) //比较的结果是true 因为两次调用getClass都将返回Pair.Class;
3.不能创建参数化类型的数组
Pair<String>[] table = new Pair<String>[10]; //error
/**
出错原因: 擦除之后,table的类型是Pair[]。
需要说明的是,只是不允许创建这些数组,而神秘数组为Pair<String>[]的变量仍然是合法的,不过不能用new Pair<String>[10]初始化这个变量
**/
4.不能实例化类型参数
下面的构造器非法
public Pair() {
first = new T();
second = new T();
}
//类型擦除会将T改变成Object
如果一定要实现可以设计API以便可以支持Class对象
public static <T> Pair<T> makePair(Class<T> c1){
try{
return new Pair<>(c1.newInstance(), c1.newInstance())
}
catch(Exceprion e){
return null;
}
}
//上面方法可以按照下列方式调用
Pair<String> p = Pair.makePair(String.class);
5.泛型类的静态上下文类型变量无效
不能在静态域或者方法中引用类型变量
public class Singleton<T>{
private static T singleInstance;
public static T getSingleInstance(){
if(singleInstance == null){
return singleInstance;
}
}
}
6.不能抛出或者铺货泛型类的实例
既不能抛出也不能捕获泛型类对象
public calss Problem<T>extends Exception{/*...*/}
//catch子句中不能使用类型变量
public static <T extends Throwable> void doWork(Class<T> t){
try{
do work
}
catch(T e){ //error:can't catch type variable
logger.global.info(...);
}
}
//不过,在异常规范中使用类型变量是允许的
public static <T extends Throwable> void doWork(Class<T> t){
try{
do work
}
catch(Throwable e){ //error:can't catch type variable
t.initCause(realCause);
throw t;
}
}
最后附上java官网的说明 链接