Java Generics数组语法

use*_*685 16 java generics syntax types

以下声明指定了哪种数据结构?

 List<ArrayList>[] myArray;
Run Code Online (Sandbox Code Playgroud)

我认为它应该声明一个数组,其中每个元素是一个List(例如,一个LinkedList或一个ArrayList),并要求每个元素List包含ArrayList对象.

我的推理:

 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
Run Code Online (Sandbox Code Playgroud)

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

因此,List<ArrayList>指定List必须包含的内容,但List<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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*ler 17

答案是数组只能保存有效类型.并且一般化的课程没有具体化.也就是说,List <ArrayList>的运行时"类型"只是List.泛型在运行时被删除(谷歌"擦除墙"更多).

所以这:

List<ArrayList>[] myArray
Run Code Online (Sandbox Code Playgroud)

真正意思:

List[] myArray
Run Code Online (Sandbox Code Playgroud)

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

Naftalin和Wadler的Java Generics and Collections一书是您对泛型问题的极好参考.或者,当然,泛型常见问题解答是您的规范在线参考.


Mar*_*ark 8

Josh Bloch先生说:

"首选列表到数组,因为数组是协变的,而泛型是不变的'

你也许可以这样做:

List<List<ArrayList>> someListArray;
Run Code Online (Sandbox Code Playgroud)

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

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


Dra*_*mon 5

List<ArrayList>[] someListArray;
Run Code Online (Sandbox Code Playgroud)

给你一个:

array of ( List of ArrayList )
Run Code Online (Sandbox Code Playgroud)

但由于Java泛型的限制(错误6229728),您只能实际创建:

array of List
Run Code Online (Sandbox Code Playgroud)

投下它:

List<ArrayList>[] someListArray = (List<ArrayList>[]) new List[5];
Run Code Online (Sandbox Code Playgroud)