Java 泛型的限制
- 泛型的限制
-
- 泛型的类型参数T 不能使用原始类型,应该是用原始类型的包装类。
- 类型参数不能用于在方法中实例化其对象
- 不能使用静态域
- 不能转换类型
- 不能使用instanceof运算符
- 不能使用数组
- 不能使用异常
-
- 通用类不允许直接或间接扩展Throwable类。
- 在一个方法中,不允许捕获一个类型参数的实例
- throws子句中允许使用类型参数。
泛型的限制
泛型的类型参数T 不能使用原始类型,应该是用原始类型的包装类。
Box<int> stringBox = new Box<int>()
上面代码(Box类 参见之前的内容)类型参数T 必须修改为Integer才不会报错。
类型参数不能用于在方法中实例化其对象
public class GenericNoInstance {
public static void main(String[] args) throws InstantiationException,
IllegalAccessException {
Box<String> stringBox = new Box<String>();
add(stringBox, String.class);
}
//编译报错,不能使用实例
public static <T> void add(Box<T> box) {
// T item = new T();
// box.add(item);
}
//非要实现实例,就是用反射(这样做 何必呢)
public static <T> void add(Box<T> box, Class<T> clazz)
throws InstantiationException, IllegalAccessException {
T item = clazz.newInstance();
box.setT(item);
System.out.println("Item has been added.");
}
}
不能使用静态域
使用泛型时,类型参数不允许为静态(static)。
由于静态变量在对象之间共享,因此编译器无法确定要使用的类型。
不能转换类型
本来类型都不确定,你转换个P哟。如果非要转换,就转换试试。但感觉没有必要。
错误示例:
Box<Integer> integerBox = new Box<Integer>();
Box<Number> numberBox = new Box<Number>();
//下面用法是错误的
integerBox = (Box<Integer>)numberBox;
使用无界通配符进行参数化,到时可以转换,但是没有必要。
private static void add(Box<?> box){
Box<Integer> integerBox = (Box<Integer>)box;
}
不能使用instanceof运算符
不能使用数组
错误示例
Box<Integer>[] arrayOfLists = new Box<Integer>[2];
因为编译器使用类型擦除,类型参数被替换为Object,用户可以向数组添加任何类型的对象。但在运行时,代码将无法抛出ArrayStoreException。
不能使用异常
通用类不允许直接或间接扩展Throwable类。
//The generic class Box<T> may not subclass java.lang.Throwable
class Box<T> extends Exception {}
//The generic class Box<T> may not subclass java.lang.Throwable
class Box1<T> extends Throwable {}
在一个方法中,不允许捕获一个类型参数的实例
public static <T extends Exception, J>
void execute(List<J> jobs) {
try {
for (J job : jobs){}
// compile-time error
//Cannot use the type parameter T in a catch block
} catch (T e) {
// ...
}
}
throws子句中允许使用类型参数。
class Box<T extends Exception> {
private int t;
public void add(int t) throws T {
this.t = t;
}
public int get() {
return t;
}
}