Java 泛型 数组语法

2022-09-03 05:11:48

以下声明指定了什么数据结构?

 List<ArrayList>[] myArray;

我认为它应该声明一个数组,其中每个元素都是一个(例如,a或an),并要求每个元素都包含对象。ListLinkedListArrayListListArrayList

我的理由:

 List<String> someList;             // A List of String objects
 List<ArrayList> someList;         // A List of ArrayList objects
 List<ArrayList>[] someListArray;  // An array of List of ArrayList objects

在运行一些测试后,我确定它接受一个数组,其中每个元素都是一个对象,并且不指定LinkedList对象包含的内容。LinkedList

因此 指定 必须包含的内容,但指定必须如何实现。List<ArrayList>ListList<ArrayList>[]List

我错过了什么吗?

这是我的测试。

import java.util.ArrayList;
import java.util.List;
import java.util.LinkedList;


public class Generics1 {

    public static void main(String[] args) {

        List<ArrayList>[] someListArray;

        someListArray = getArrayWhereEachElementIsAnArrayListObject();
        // Why does this satisfy the declaration?
        //someListArray[0] => ArrayList object holding Strings

        someListArray= getArrayWhereEachElementIsAListOfArrayListObjects();
        //someListArray[0] => ArrayList object holding ArrayList objects

    }

    public static List[] getArrayWhereEachElementIsAnArrayListObject() {
        List[] arrayOfLists = new ArrayList[2];
        arrayOfLists[0] = getStringList();
        arrayOfLists[1] = getIntegerList();
        return arrayOfLists;
    }

  public static List[] getArrayWhereEachElementIsAListOfArrayListObjects() {   

        List list1 = new ArrayList();
        list1.add(getArrayList());

        List list2 = new ArrayList();
        list2.add(getArrayList());

        List[] arrayOfListsOfArrayLists = new ArrayList[2];
        arrayOfListsOfArrayLists[0] = list1;
        arrayOfListsOfArrayLists[1] = list2;
        return arrayOfListsOfArrayLists;
    }

    public static List getStringList() {
        List stringList= new ArrayList();
        stringList.add("one");
        stringList.add("two");
        return stringList;
    }


    public static List getIntegerList() {
        List intList= new ArrayList();
        intList.add(new Integer(1));
        intList.add(new Integer(2));
        return intList;
    }

    public static ArrayList getArrayList() {
        ArrayList arrayList = new ArrayList() ;
        return arrayList;
    }
}

答案 1

答案是数组只能保存已初始化的类型。并且生成的类不会重新初始化。也就是说,List<ArrayList> 的运行时“类型”只是 List。泛型在运行时被删除(谷歌“擦除墙”了解更多信息)。

所以这个:

List<ArrayList>[] myArray

真正的意思是:

List[] myArray

没有类型安全的方式来声明您尝试声明的内容。通常,在这种情况下,我建议您使用List而不是数组。有些人甚至建议,既然我们有泛型,就应该将数组视为已弃用的类型。我不能说我愿意走那么远,但你应该考虑一下,每当你被一个数组所吸引时,一个集合是否是一个更好的选择。

Naftalin和Wadler的Java Generics and Collections一书是您可能遇到的有关泛型问题的绝佳参考。或者,当然,泛型常见问题解答是您的规范在线参考。


答案 2

乔希·布洛赫先生 说:

“更喜欢列表而不是数组,因为数组是协变的,泛型是不变的。

你也许可以做:

List<List<ArrayList>> someListArray;

这可能会给一些性能带来一些打击(甚至不值得注意),但你将在编译时获得更好的类型安全性。

但我认为问题应该更多地围绕“为什么”你需要这个?