【问题标题】:Why autoboxing doesn't work in arrays?为什么自动装箱在数组中不起作用?
【发布时间】:2018-02-05 16:03:10
【问题描述】:

我不明白为什么这段代码没有编译:

 Object[] arr = new int[3];

我不需要此代码即可工作。我只是想了解为什么自动装箱在这种情况下不起作用的原因

【问题讨论】:

  • int 是一个原语.. 你需要明确地使用 Integer 包装器....
  • int 不是 Object 的实例。你需要使用 Integer 来代替
  • 如果可能的话,还要避免将这些结构与数组一起使用:如果您不想在某处获得ArrayStoreException,请使用等于实际数组类型的变量类型。

标签: java types type-conversion


【解决方案1】:

装箱将原始类型的实例转换为相应包装器类型的实例。

不适用于数组类型。

为什么?

  • 因为这就是语言设计者设计 Java 的方式,以及 JLS 指定的内容。详情在JLS 5.1.7

JLS 作者没有对这一决定做出解释。但是,有很多原因。这里有几个比较明显的。

  • 效率。将int[] 转换为Object[] 需要访问和转换数组的所有元素。这是昂贵的 (O(N)) ... 而不是程序员应该在某些语法后面隐藏的东西。

  • 对数组进行装箱必然会创建一个与原始数组本质上不同的新数组。您可以通过以下方式说明这一点:

    int[] ints = new int[]{1,2,3};
    Integer[] arr = ints;  // hypothetical boxing of the elements
    // What does ints.equals(arr) return?
    
    array[1] = 0;
    // What does ints[0] contain now?
    

    相比之下,(真正的)装箱和拆箱仅在比较指针时才可区分的值之间进行转换......即使那样,也不可靠。

底线是,扩展装箱和拆箱会引入难以解决的效率和概念问题。

【讨论】:

    【解决方案2】:

    根据JLS 4.3.1,数组是 Java 中的对象

    因此,不能将 int[] 分配给 Object[],反之亦然,因为它们是不兼容的类型。

    虽然,自动装箱确实适用于数组的元素:

    int[] a = new int[3];
    a[0] = new Integer(0);
    a[1] = 1;
    a[2] = new Integer(2);
    
    System.out.println(a[0]);
    System.out.println(a[1]);
    System.out.println(a[2]);
    

    输出:

    0
    1
    2
    

    【讨论】:

      【解决方案3】:

      this回复Why do we use autoboxing and unboxing in Java?,我会引用相关细节来回答你的问题:

      原始变量不能以相同的方式互换,也不能 彼此,也不与Object最明显的原因 (但不是唯一的原因)是它们的大小不同。 这使得 原始类型在这方面不方便,但我们仍然需要它们 在语言中(原因主要归结为性能)。

      因此,另一方面,对你有用的是:

      Object[] arr = new Integer[3];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-16
        • 2020-04-18
        • 2011-11-16
        • 2015-02-23
        • 2011-10-11
        • 1970-01-01
        相关资源
        最近更新 更多