课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > 不能初始化泛型参数和数组
  • 不能初始化泛型参数和数组

    发布:昆明Java培训      来源:达内新闻      时间:2016-09-30

  • 昆明Java培训机构的老师知道,泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码:

    class Test<T> {

    private T t = new T();

    private T[] tArray = new T[5];

    private List<T> list = new ArrayList<T>();

    }

    这段代码有神么问题呢?t、tArray、list都是类变量,都是通过new声明了一个类型,看起来非常相似啊!但这段代码是编译不过的,因为编译器在编译时需要获得T类型,但泛型在编译期类型已经被擦除了,所有new T()和new T[5]都会报错(有人可能会有疑问,泛型类型可以擦除为顶级Object,那T类型擦除成Object不就可以编译了吗?这样也不行,泛型只是Java语言的一部分,Java语言毕竟是一个强类型、编译型的安全语言,要确保运行期的稳定性和安全性就必须要求在编译器上严格检查)。可为什么new ArrayList<T>()却不会报错呢?

    这是因为ArrayList表面是泛型,其实已经在编译期转为Object了,我们来看一下ArrayList的源代码就清楚了,代码如下:

    1 public class ArrayList<E> extends AbstractList<E> implements List<E>,

    2        RandomAccess, Cloneable, java.io.Serializable {

    3    //容纳元素的数组

    4    private transient Object[] elementData;

    5

    6    //构造函数

    7    public ArrayList() {

    8        this(10);

    9    }

    10

    11    //获得一个元素

    12    public E get(int index) {

    13        rangeCheck(index);

    14        //返回前强制类型转换

    15        return elementData(index);

    16    }

    17    /*其它代码略*/

    18

    19 }

    注意看elementData的定义,它容纳了ArrayList的所有元素,其类型是Object数组,因为Object是所有类的父类,数组又允许协变(Covariant),因此elementData数组可以容纳所有的实例对象。元素加入时向上转型为Object类型(E类型转换为Object),取出时向下转型为E类型,如此处理而已。

    在某些情况下,我们需要泛型数组,那该如何处理呢?代码如下:

    1 class Test<T> {

    2    //不再初始化,由构造函数初始化

    3    private T t;

    4    private T[] tArray;

    5    private List<T> list = new ArrayList<T>();

    6

    7    //构造函数初始化

    8    public Test() {

    9        try {

    10            Class<?> tType = Class.forName("");

    11            t = (T) tType.newInstance();

    12            tArray = (T[]) Array.newInstance(tType, 5);

    13        } catch (Exception e) {

    14            e.printStackTrace();

    15        }

    16    }

    17 }

    此时,运行就没有什么问题了,剩下的问题就是怎么在运行期获得T的类型,也就是tType参数,一般情况下泛型类型是无法获取的,不过,在客户端调用时多传输一个T类型的class就会解决问题。

    类的成员变量是在类初始化前初始化的,所以要求在初始化前它必须具有明确的类型,否则就只能声明,不能初始化。

    了解详情请登陆昆明达内Java培训官网(km.Java.tedu.cn)!

    推荐文章

上一篇:Java的泛型是可以擦除的

下一篇:强制声明泛型的实际类型

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:12/29

Java--零基础业余班

Java--零基础业余班

开班日期:12/29

Java--周末提升班

Java--周末提升班

开班日期:12/29

Java--零基础周末班

Java--零基础周末班

开班日期:12/29

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56