public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
List<Number> list2=list;
//编译错误.
list2.add(new Float(19.0f));
}
|
class Foo<T>{
public void dosomething(T param){
T copy=new T(param);//语法错误.
}
}
|
class Foo<T extends Cloneable>{
}
|
class Foo{
}
|
class Foo{
}
|
class ArrayList<V>{
}
|
class ArrayList<V> {
private V[] backingArray;
public ArrayList() {
backingArray = (V[]) new Object[DEFAULT_SIZE];
}
}
|
最好的方法是: 向构造方法中,传入类对象,这样,在运行时,就可以知道T的值了。不采用这种方法的原因是,它无法与之前版本的Collections框架相兼容。
public class ArrayList<V> implements List<V> {
}
|
public static Object newInstance(Class<?> componentType, int length) |
而不是类型安全的:
public static<T> T[] newInstance(Class<T> componentType, int length) |
为何 Array 用这种方式进行泛化呢?同样是为了保持向后兼容。要创建基本类型的数组,如 int[] , 可以使用适当的包装器类中的 TYPE 字段调用 Array.newInstance() (对于 int ,可以传递 Integer.TYPE 作为类文字)。用 Class<T> 参数而不是 Class<?> 泛化 Array.newInstance() ,对 于引用类型有更好的类型安全,但是就不能使用 Array.newInstance() 创建基本类型数组的实例了。也许将来会为引用类型提供新的 newInstance() 版本,这样就两者兼顾了。
在这里可以看到一种模式 —— 与泛型有关的很多问题或者折衷并非来自泛型本身,而是保持和已有代码兼容的要求带来的副作用。