Arrays.deepEquals为int []提供错误,但适用于Integer []

时间:2013-10-26 15:30:45

标签: java arrays eclipse wrapper autoboxing

我在eclipse Kepler中使用以下程序

import java.util.Arrays;

public class Mainn {
    public static void main(String[] args) {    
        int[] a = {1, 2};
        int[] b = {1, 2};

        System.out.println(Arrays.deepEquals(a, b));    
    }
}

它给出了一个关于int[]参数不适用于Object[]形式参数的编译时错误。但是当我使用Integer[]而不是int[]作为数组ab的数据类型时,相同的程序正常工作。

我很困惑。根据{{​​3}},编译器会在原语和包装类之间自动进行自动装箱和取消装箱,因此它应该在这里工作。但它没有用。为什么呢?

2 个答案:

答案 0 :(得分:4)

subtyping arrays的规则如下,来自Java语言规范,其中>表示是超类型

  

如果S和T都是参考类型,那么S[]> T[] iff S> T

     

...

     
      
  • 如果P是基本类型,则:   
        
    • Object >1 P[]
    •   
    • Cloneable >1 P[]
    •   
    • java.io.Serializable >1 P[]
    •   
  •   

其中>1表示是直接超类型

在这种情况下,SObjectTInteger,因为Integer是[{1}}的子类型,因此{{ 1}}是Object的子类型,您可以将其用作期望Integer[]的方法的参数。

但是,对于原始Object[]Object[]int的超类型,因此Object不能用于需要int[]的地方

包装类的概念在这里不适用。

答案 1 :(得分:4)

自动装箱适用于int(转换为Integer)等原语,但不适用于数组 - int[]类型的对象不会自动提升为Integer[] < / p>

我没有任何具体来源为什么这个设计选择,但有几点似乎相关:

  • int[]已经是一个对象,而自动装箱适用于基元。自动装箱int[](以及其他情况)会使自动装箱的标准显着复杂化(在某些情况下可能导致意外行为)
  • 自动装箱不是零成本操作。将int[]加到Integer[]意味着创建一个新数组,然后为数组中的每个元素创建一个新包装器。通常,Java会试图避免隐式执行昂贵的操作。