使用泛型时,有一些限制需要牢记,他们涉及创建类型形参的对象,静态成员,异常和数组等.下面分别介绍:
1.类型形参不能实例化
不能创建类型形参的实例,例如下面的代码:
class Gen<T> { T ob; Gen() { ob = new T(); } }
2.对静态成员的限制
静态成员不能使用由包含类(enclosing class)声明的类型形参.例如,下面类的所有静态成员都是非法的:
class Gen<T> { static T ob; static T getOb() { return ob; } }
尽管不能声明使用包含类声明的类型形参的静态成员,但是可以声明静态泛型方法,他们定义了自己的类型形参.
3,泛型数组限制
数组有两个重要的泛型限制:首先,不能实例化基类型为类型形参的数组;其次,不能创建特定类型泛型应用的数组,下面的程序演示了这两种限制:
public class test2 { public static void main(String args[]) { Integer n[] = {1,2,3,4,5}; Gen<Integer> iOb = new Gen<Integer>(50,n); Gen<?> gens[] = new Gen<?>[10]; //Gen<Integer> gens[] = new Gen<Integer>[10]; //can't create an array of type-specific genric references } } class Gen<T extends Number> { T ob; T vals[]; Gen(T o,T[] nums) { ob = o; vals = nums; // vals = new T[10]; can't create array of T } }
正如程序所示,声明类型为T的数组的引用是有效的,如下所示:
T vals[];
但是不能实例化T类型的数组,如下面注释掉的代码所示:
vals = new T[10]; can't create array of T
原因是编译器不知道要实际创建何种类型的数组,但是,创建对象时可以把一个类型兼容的数组的引用传递给Gen(),并且把该引用赋值给vals,如下所示:
vals = nums;
该语句是有效的,因为传递给Gen的数组是已知的类型,他与对象创建时T的类型相同.注意,在main()中不能声明引用特定泛型类型的数组,例如,下面的语句将无法编译成功:
Gen<Integer> gens[] = new Gen<Integer>[10];
4.泛型异常限制
泛型类不能扩展Throwable,这意味着不能创建泛型异常类.