ArrayList实例化内部T []数组

时间:2017-04-02 19:48:23

标签: java arrays arraylist

我发现如果你有一个泛型类,其数组依赖于该类的类型参数,则无法以通常的方式初始化该数组:

class Foo<T>  {
    private T[] a;

    Foo()  {
       a=new T[5]; //doesn't compile
    }
}

你只能这样做:

class Foo<T>  {
        private T[] a;

        Foo(T[] a)  {
           this.a=a;
        }
    }

但是这段代码是可能的:

ArrayList<Integer> list=new ArrayList<>();

为什么呢? ArrayList如何克服这个问题?我查看了它的代码,但无法弄明白。看起来它只是将事物存储在Object[]数组中,这似乎是错误的。

2 个答案:

答案 0 :(得分:3)

ArrayList内的数组始终为Object[]类型,因为您可以将任何内容存储在此类数组中。类型参数在方法级别上启用类型安全,这是重要的。

编辑以按要求解决类型擦除主题:

Java中的类型擦除意味着泛型类型参数仅在编译期间出现,其中最重要的是确保类型安全。泛型已经通过这种方式实现,以保持较新版本的Java与旧版本兼容。

这样做的缺点是永远不能实例化泛型类型,因为它在运行时永远不会被人知道。

答案 1 :(得分:2)

将此视为一个类比:

你拥有一家铅笔公司。你在车里用铅笔开车。

你可以把鲜花放在你的面包车里:毕竟它是一辆面包车,所以你可以把任何你想要的东西放在那里。棒球,大猩猩,氦气球。

但你选择不这样做:你是一家铅笔公司,所以你把它放进你的货车里就是铅笔。如果您的汉堡公司的朋友要求您在面包车上放一些汉堡肉饼,您会拒绝:这辆面包车只适用于铅笔。

所以,当你从你的面包车里取出一些东西时,你知道它会成为一支铅笔,因为你确保通过那些门进入的唯一东西就是铅笔。

所以它是ArrayList<T>:你可以存储Object[]中的任何内容,但你不能:你只能存储T在那里,因为你只能通过add(T)addAll(Collection<? extends T>)方法向它添加内容。

因此,将您的元素存储在Object[]而不是更具体的类型数组中并不重要:您将从{{1}中获得的唯一内容} - 通过其ArrayList<T>(等)方法 - 是get()或其子类型之一的实例。