从方法签名可以很清楚地看出,该方法接受类型为 Object[] 的参数,但该方法对于原始多维数组仍然工作得很好?(如 int[][]、float[][] 等) (但是它显示原始一维数组的错误(如 int[]、float[] 等))
例如:
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[])"*/
同样的问题是 Arrays.deepToString(Object[]) 从方法签名中可以清楚地看出,该方法也接受 Object[] 类型的参数,但对于原始多维数组仍然可以正常工作?(如 int[][ ],float[][] 等)(但是它显示原始一维数组的错误(如 int[],float[] 等))
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[])"
编辑:
我也想补充几点。
1:Java 中的子类型:
What is subtyping?
=>子类型是面向对象的一个关键特性 Java 等编程语言。在 Java 中,如果 S 是 T 的子类型 扩展或实现 T。子类型化是可传递的,这意味着如果 R 是一个 S 的子类型,则 R 也是 T 的子类型(T 是两者的超类型 沙R).String是Object的子类型,因为String类是一个 Object 类的子类。
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:数组类型之间的子类型化:
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:数组类型的直接超类是 Object。
4:每个数组类型都实现接口 Cloneable 和 java.io.Serializable.
5:在Java编程语言中,数组是对象,是动态的 创建并可以分配给 Object 类型的变量。的所有方法 可以在数组上调用类对象。
6:对象是类实例或数组。
7:参考值(通常只是引用)是指向这些的指针 对象,以及一个特殊的空引用,它不引用任何对象。
8:类实例由类实例显式创建 创作表达。
9:数组是由数组创建表达式显式创建的。
问的字面问题是:
为什么
适用于像Arrays.deepEquals(Object[] arr1, Object[] arr2)
、int[][]
等原始多维数组?float[][]
对此的简单回答是“因为 javadoc 是这么说的”。详见@老狗程序员的回答
但是被问到的real问题(据我所知)是:
为什么它适用于
、int[][]
等但不适用于float[][]
、int[]
等?float[]
这是子类型化和多维数组类型在 Java 中工作方式的结果。在 Java 中确实没有多维数组类型1。例如,
int[][]
类型实际上是一个“int
的数组的数组”。 “int
的数组”部分是原始数组类型。
根据Java子类型规则,所有数组(包括一维原始数组如
int[]
)都是Object
的子类型。这意味着 int[][]
(“int
的数组的数组”)是 Object[]
(“Object
的数组”)的子类型。
相比之下,
int[]
不是 Object[]
的子类型,因为 int
不是 Object
的子类型。
这意味着
Arrays.deepEquals
不适用于原始数组(即该方法不适用于参数)但它确实适用于 arrays of 原始数组;即多维原始数组。实际的解决方案是在比较一维原始数组时使用 Arrays.equals
重载。
1 - JLS 第 1 章指出:“该语言支持数组的数组,而不是多维数组。”
之所以有效,是因为
Arrays.deepEquals
是为二维基元数组而编写的。 API 指定它将起作用。这是引用,其中我强调了最相关的行:
如果满足以下任何条件,则两个可能为空的元素 e1 和 e2 深度相等:
- e1 和 e2 都是对象引用类型的数组,Arrays.deepEquals(e1, e2) 将返回 true
- e1 和 e2 是相同原始类型的数组,适当重载 Arrays.equals(e1, e2) 将返回 true。
- e1 == e2
- e1.equals(e2) 将返回 true。 请注意,此定义允许任何深度的空元素。
它是如何工作的?我们可以查看该方法的源代码。它包含一个
if ... else
链,用于检查每个参数是否都是 aninstanceof
相同类型的原始数组。
deepToString
方法的代码包含一个类似的if ... else
链。