1、首先看这个泛型:public class TestGenericArray <E>{ private E[]elements; private int size=0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public TestGenericArray(){ elements=new E[DEFAULT_INITIAL_CAPACITY]; } public E pop(){ if(size==0){ throw new EmptyStackException(); } E reslut=elements[--size]; elements[size]=null; return reslut; }}在new E[DEFAULT_INITIAL_CAPACITY];这一行会有编译错误,告诉你不能创建泛型数组。具体见下图。
2、那我们要怎么做呢?有两种办法解决上面的错误,第一种是通过创建一个Object类型的数组,然后显示转换为E[]类型。见下面的代码:import java.util.EmptyStackException;public class TestGenericArray <E>{ private E[]elements; private int size=0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public TestGenericArray(){ elements=(E[])new Object[DEFAULT_INITIAL_CAPACITY]; } public E pop(){ if(size==0){ throw new EmptyStackException(); } E reslut=elements[--size]; elements[size]=null; return reslut; }}注意此时在elements=(E[])new Object[DEFAULT_INITIAL_CAPACITY];这一行会有编译警告,提示我们这个Type safety: Unchecked cast from Object[] to E[],类型安全的警告,即没有检验从Object数组转化为E的类型安全性。这种做法虽然能够消除编译错误,但是有警告,也就是告诉我们这样不是类型安全的。如果这样做我们必须自己保证elements数组中的数据是类型安全的才可以这样做。当我们确认未受检的转换是类型安全的,那么我们要在最小的范围内禁止警告。
3、另外一种能够消除创建泛型数组错误的是声明数组域时,直接声明为Object类型的数组,当获取数组元素时把对应的元素转换为E泛型类型。public class TestGenericArray <E>{ private Object[]elements; private int size=0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public TestGenericArray(){ elements=new Object[DEFAULT_INITIAL_CAPACITY]; } public E pop(){ if(size==0){ throw new EmptyStackException(); } E reslut=(E)elements[--size]; elements[size]=null; return reslut; }}第二种方法的重点在数组声明和获取元素上面。但是这种做法会有警告,见下图。同上面的方法一样,同样提示的是未受检的类型转换问题。可以通过@SuppressWarning注解取消警告,但是要在尽可能小的范围禁止,否则编译器能做的正常检测也会被禁止,通常不要在类上加该注解。加注解后的代码见图2.
4、综合两种方法,其实本质上都没有创建泛型数组,java也不允许这样做。只是通过创建Object数组然后转化为泛型类型而已。方法一是一次性转换整个数组,而方法二是每次取数组元素时才进行转换,实际上都是相同的处理。