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 .
The literal question asked is:
Why does
Arrays.deepEquals(Object[] arr1, Object[] arr2)
work for primitive multidimensional arrays likeint[][]
,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 forint[]
,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."