【问题标题】:Java array of lists working when type of list is different [duplicate]当列表类型不同时,Java列表数组工作[重复]
【发布时间】:2019-07-08 17:32:35
【问题描述】:

我有以下代码工作,但我不确定为什么它不会引发异常:

List[] x=new ArrayList[2];
x[0]=new ArrayList<Integer>();
x[1]=new ArrayList<String>();
x[0].add("test");
x[1].add(5);
System.out.println(x[0]);
System.out.println(x[1]);

打印出来:

[test]
[5]

x[0] 是整数数组,它添加字符串没有任何问题。 x[1] 是字符串数组,它添加整数没有任何问题。

它是如何工作的?

【问题讨论】:

  • 一个很好的例子,说明为什么你不应该使用原始类型。请注意,泛型在运行时会被删除。所以如果它编译,它也会运行。泛型仅在编译时提供安全性。使用原始类型,您有效地绕过了所有安全性。

标签: java arrays arraylist


【解决方案1】:

首先,这与数组无关。以下表现出相同的行为:

List x = new ArrayList();
x = new ArrayList<Integer>();
x.add("test");
System.out.println(x);

这样做的关键原因是 x 被声明为具有 raw List 类型。更全面的讨论见What is a raw type and why shouldn't we use it?

【讨论】:

    【解决方案2】:

    您已经声明了一个原始类型列表数组。编译代码后,运行时不存在通用值。所以基本上你的列表是List&lt;Object&gt; 类型的。

    • "test"String,基本上是 Object
    • 5 自动装箱为 Integer,这也是 Object

    所以你的编译器不会抛出任何错误。如果您使用的是 IDE,它可能会警告您:

    作为原始类型“java.util.List”的成员对“add(E)”的未经检查的调用

    (来自 IntelliJ)

    【讨论】:

      【解决方案3】:

      您的数组x 被定义为原始类型List,因此类型参数被删除,您最终调用add(Object),在整数的情况下,它依赖于自动装箱。

      如果您尝试将 x[0]x[1] 别名化为预期类型的​​变量,您可能会遇到一开始就预料到的编译错误:

      List<Integer> x0 = (ArrayList<Integer>) x[0];
      List<String> x1 = (ArrayList<String>) x[1];
      x0.add("test"); // Compilation error
      x1.add(5);      // Compilation error
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-19
        • 1970-01-01
        • 1970-01-01
        • 2011-12-01
        • 1970-01-01
        • 2019-01-07
        相关资源
        最近更新 更多