2

From method signature it is very clear that method accepts the argument of type Object[] but still this method works perfectly fine for primitive multidimensional arrays ?(like int[][],float[][] etc) (However it shows error for primitive one dimensional array (like int[],float[] etc))

Ex:

      int[][]arr=new int[2][3];
      arr[0][0]=1;
      arr[0][1]=2;
      arr[0][2]=3;
      arr[1][0]=4;
      arr[1][1]=5;
      arr[1][2]=6;
      int[][]arr1=new int[2][3];
      arr1[0][0]=1;
      arr1[0][1]=2;
      arr1[0][2]=3;
      arr1[1][0]=4;
      arr1[1][1]=5;
      arr1[1][2]=6;

      System.out.println(Arrays.deepEquals(arr,arr1));

      Output: true


Ex:  
     int[]arr={1,2,3,4,5};
     int[]arr1={1,2,3,4,5};
     System.out.println(Arrays.deepEquals(arr,arr1));//Error
/*"The method deepEquals(Object[], Object[]) in the type Arrays is not applicable for the arguments (int[], int[])"*/

the same issue is with Arrays.deepToString(Object[]) From method signature it is very clear that this method too accepts the argument of type Object[] but still it works perfectly fine for primitive multidimensional arrays ?(like int[][],float[][] etc)(However it shows error for primitive one dimensional array (like int[],float[] etc))

  Ex:
      int[][]arr=new int[2][3];
      arr[0][0]=1;
      arr[0][1]=2;
      arr[0][2]=3;
      arr[1][0]=4;
      arr[1][1]=5;
      arr[1][2]=6;

      System.out.println(Arrays.deepToString(arr));

      Output: [[1, 3, 0], [4, 5, 6]]


 Ex:

     int[]arr={1,2,3,4,5}; 
     System.out.println(Arrays.deepToString(arr)); //Error
    //"The method deepToString(Object[]) in the type Arrays is not applicable for the arguments (int[])"

Edit:

I would also like to add few points from my end as well.

1: Subtyping in Java :

What is subtyping?

=>Subtyping is a key feature of object-oriented programming languages such as Java. In Java, Sis a subtype of T if S extends or implements T. Subtyping is transitive, meaning that if R is a subtype of S, then R is also a subtype of T (T is the super type of both Sand R).String is a subtype of Object, because the String class is a subclass of the Object class.

int is not a subtype of Object, because none of Java's primitive types 
are subtypes of any reference type.

StringBuilder is not a subtype of String, because the StringBuilder 
class is not a subclass of the String class.

 HashMap<Candidate,Double> is a subtype of Map<Candidate,Double>, 
 because the HashMap class implements the Map interface and the type 
 parameters match.

 HashMap<Candidate,Double> is not a subtype of Map<String,Ballot>, even 
 though the HashMap class implements the Map interface, because the type 
 parameters do not match.

2: Subtyping among Array Types :

The following rules define the direct supertype relation among array 
types:

If S and T are both reference types, then S[] >1 T[] iff S >1 T.

Object >1 Object[]

Cloneable >1 Object[]

java.io.Serializable >1 Object[]

If P is a primitive type, then:

Object >1 P[]

Cloneable >1 P[]

java.io.Serializable >1 P[]

3: The direct superclass of an array type is Object.

4: Every array type implements the interfaces Cloneable and java.io.Serializable.

5:In the Java programming language, arrays are objects , are dynamically created, and may be assigned to variables of type Object. All methods of class Object may be invoked on an array.

6: An object is a class instance or an array.

7: The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.

8: A class instance is explicitly created by a class instance creation expression.

9: An array is explicitly created by an array creation expression .

2 Answers2

2

The literal question asked is:

Why does Arrays.deepEquals(Object[] arr1, Object[] arr2) work for primitive multidimensional arrays like int[][], float[][] etc?

The simple answer to that is "because the javadoc says so". See @Old Dog Programmer's answer for details.


But the real question being asked (as I understand it) is:

Why does it work for int[][], float[][] etc but not for int[], float[] etc?

This is a consequence of the way that subtyping and multidimensional array types work in Java. In Java there is really no such thing as a multidimensional array type1. For example, the type int[][] is actually an "array of arrays of int". The "array of int" part is a primitive array type.

According to the Java subtyping rules, all arrays (including 1-D primitive arrays such as int[]) are subtypes of Object. That means that int[][] ("array of arrays of int") is a subtype of Object[] ("array of Object").

By contrast an int[] is NOT a subtype of Object[] since int is not a subtype of Object.

That means that Arrays.deepEquals doesn't work for primitive arrays (i.e. the method is not applicable to the arguments) but it does work for arrays of primitive arrays; i.e. multidimensional primitive arrays. The practical solution is to use the Arrays.equals overloads when comparing 1-D primitive arrays.


1 - JLS Chapter 1 states: "The language supports arrays of arrays, rather than multidimensional arrays."

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

It works because Arrays.deepEquals was written to work for 2D arrays of primitives. The API specifies it will work. Here is a quote, in which I emphasized the most relevant line:

Two possibly null elements e1 and e2 are deeply equal if any of the following conditions hold:

  • e1 and e2 are both arrays of object reference types, and Arrays.deepEquals(e1, e2) would return true
  • e1 and e2 are arrays of the same primitive type, and the appropriate overloading of Arrays.equals(e1, e2) would return true.
  • e1 == e2
  • e1.equals(e2) would return true. Note that this definition permits null elements at any depth.

How was it made to work? We can look at the source code for the method. It contains an if ... else chain that checks if the parameters are each aninstanceof the same type of primitive array.

The code for the deepToString method contains a similar if ... else chain.

Old Dog Programmer
  • 901
  • 1
  • 7
  • 9