有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

参数化类型的java数组

我很难弄清楚在下面的RHS中需要什么类型参数

ArrayList<Pair<ParseNode,ParseNode>>[] nodes = new ArrayList[indexes.length];

为什么<Pair<ParseNode,ParseNode>>的副本不合法


共 (3) 个答案

  1. # 1 楼答案

    混凝土参数化类型的数组本质上是破碎的。请记住,数组是协变的,数组类型检查是一个运行时操作。在运行时,所有泛型都已被类型擦除,因此数组存储检查无法区分<Pair<ParseNode, ParseNode>><Pair<BigInteger,IOException>>

    泛型的基本约定是“我,编译器,承诺如果您编写的代码不生成警告,您将永远不会在运行时得到类强制转换异常。”

    编译器也不能向您保证,如果将非ArrayList<Pair<ParseNode,ParseNode>>的内容放入该数组中,它将能够给您一个编译时错误。如果您添加了错误的类型,运行时系统也不能保证您将获得ArrayStoreException(就像语言规范所说的那样),而不是在稍后将其取出时获得ClassCastException。(第二部分是为什么它实际上是非法的,而不仅仅是一个警告,它将导致一个不符合语言规范的数组。)

    因此,它不允许您以这种方式声明它们,并强制您承认“不安全”警告。这样,它就说:“我告诉过你,我不能保证使用这个数组不会导致任何类强制转换异常,你必须确保你只在这里放正确的东西。”

  2. # 2 楼答案

    不要使用数组。使用另一个ArrayList

    ArrayList<List<Pair<ParseNode,ParseNode>>> listOfLists = new ArrayList<List<Pair<ParseNode,ParseNode>>>();
    
    listOfLists.add(new ArrayList<<Pair<ParseNode,ParseNode>>());
    
  3. # 3 楼答案

    Java不支持泛型数组。数组是协变的,泛型不是。这意味着如果类A扩展了类B,那么A[]也是B[]。和代码

    A[] a = new A[10];
    B[] b = a;
    

    这是合法的

    但泛型的情况不同。即使T扩展了X,也不能将Foo<T>分配给Foo<X>,因此Foo<T>[]的元素不能保证类型安全

    编辑 请原谅我只是链接一下,但我发现了Java theory and practice: Generics gotchas篇文章,它比我想象的更好地解释了关于数组协方差的一切