Java中的多维数组扩展了哪个类?

我需要知道Java中哪些类多维数组完全延伸?

当我们分配

Object[] ref=new int[]{1,2,3}; 

编译器抱怨对象是不同类型的。 所以似乎一维数组扩展了Object ; 我已经知道了。

但是当我们分配时

 Object[] ref2=new int[][]{{1,2,3},{4,5,6}}; 

编译器不会抱怨。 所以似乎二维数组扩展了Object[]

但是当我打印它的超类名称时:

 System.out.println(ref2.getClass().getSuperclass().getName()); 

我有java.lang.Object

所以有人能解释这里发生了什么吗?

Java中的多维数组实际上只是数组(数组)*的数组。

此外,数组被视为Object的子类。

所以,你的int[][]是一个Object[] (组件类型为int[] ),还有一个Object (因为所有数组都是对象)

然而, int[]不是Object[] (但它仍然是Object )。

所以似乎二维数组扩展了Object []

我不确定“延伸”是否适用于此。 数组在Java类型系统中有一个特殊的位置,与其他对象的工作方式略有不同。 二维数组肯定是Object []。 但是如果你问的是超类,那么任何一种数组都有的唯一超类是Object。 所有数组也都是Cloneable和Serializable。

你的inheritance树看起来像这样:

  1. ref2 -int int[][]
  2. ref2 是一个 Object[]
  3. ref2 是一个 Object

这是一段代码片段,说明了我的意思:

 Object ref2 = new int[][]{{1,2,3}, {4,5,6}}; System.err.println("ref2: " + (ref2 instanceof int[][]) + " " + (ref2 instanceof Object[])); 

你应该看到类似的东西:

 ref2: true true 

Java中的数组是协变的。 这意味着如果TSubTSuper[]的子类型,则TSub[]TSuper[]的子类型。

你有int[][]这是一个int[]数组。 现在,正如其他人所指出的,Java中的任何数组都是Object的子类型,因此int[]Object的子类型。 因此,由于数组协方差, int[][]Object[]的子类型(在上面的协方差定义中替换TSub = int[]TSuper = Object )。

编辑 – 为了弄清楚为什么协方差在这里很重要,请考虑使用List做同样的事情是行不通的:

 List ref2 = new List() 

当我们分配

 Object[] ref=new int[]{1,2,3}; 

编译器抱怨

那是因为int不是Object的子类型, int.class.getSuperclass()返回null 。 请记住,在Java中,原始值(整数,长整数,双精度数等)不是对象。

所以似乎二维数组扩展了Object []。
但是当我打印它的超类名称时:

  System.out.println(ref2.getClass().getSuperclass().getName()); 

我有java.lang.Object。

数组更像是接口,因为它们可以进行多重inheritance。 但就Java接口而言,它们并不是真正的接口。

 class A {} interface I {} class B extends A implements I {} B[][] bArray = new B[1][1]; System.out.println(bArray instanceof A[][]); System.out.println(bArray instanceof I[][]); System.out.println(bArray instanceof Object[]); System.out.println(bArray.getClass().getSuperclass()); for (Class i: bArray.getClass().getInterfaces()) System.out.println(i); System.out.println(I[][].class.isAssignableFrom(bArray.getClass())); System.out.println(I[][].class.isInstance(bArray)); 

输出:

 true true true class java.lang.Object interface java.lang.Cloneable interface java.io.Serializable true true 

此外,Java违反了Liskov替换原则,因为

 B[] bArray = new B[1]; A[] aArray = bArray; // bArray[0] = new A(); // causes a compile error aArray[0] = new A(); // compiles, but causes runtime exception