Java中的多维数组扩展了哪个类?
我需要知道Java中的多维数组到底扩展了哪个类 当我们分配Java中的多维数组扩展了哪个类?,java,arrays,multidimensional-array,Java,Arrays,Multidimensional Array,我需要知道Java中的多维数组到底扩展了哪个类 当我们分配 Object[] ref=new int[]{1,2,3}; Object[] ref2=new int[][]{{1,2,3},{4,5,6}}; Object[] ref=new int[]{1,2,3}; 编译器抱怨对象的类型不同。因此,一维数组似乎扩展了对象;我已经知道了 但是当我们分配 Object[] ref=new int[]{1,2,3}; Object[] ref2=new int[][]{{1,2,3},{4
Object[] ref=new int[]{1,2,3};
Object[] ref2=new int[][]{{1,2,3},{4,5,6}};
Object[] ref=new int[]{1,2,3};
编译器抱怨对象的类型不同。因此,一维数组似乎扩展了对象;我已经知道了
但是当我们分配
Object[] ref=new int[]{1,2,3};
Object[] ref2=new int[][]{{1,2,3},{4,5,6}};
Object[] ref=new int[]{1,2,3};
编译器不会抱怨的。因此,似乎二维数组扩展了Object[]
但当我打印它的超类名称时:
System.out.println(ref2.getClass().getSuperclass().getName());
System.out.println(ref2.getClass().getSuperclass().getName());
我得到了java.lang.Object
有人能解释一下这里发生了什么吗?Java中的多维数组实际上只是数组的数组(数组的数组)* 此外,数组被认为是对象的子类 因此,您的
int[][]
是一个对象[]
(具有组件类型int[]
),也是一个对象(因为所有数组都是对象)
然而,int[]
不是对象[]
(但它仍然是对象
)
看来二维数组扩展了Object[]
我不确定这里的“扩展”是否合适。数组在Java类型系统中有一个特殊的位置,其工作方式与其他对象略有不同。二维数组肯定是一个对象[]。但是如果你问的是超类,任何类型的数组唯一的超类就是Object。所有数组也可克隆和序列化。您的继承树如下所示:
参考2 is-aint[][]
参考2 is-a对象[]
参考2 is-a对象
下面是一段代码片段,说明了我的意思:
Object ref2 = new int[][]{{1,2,3}, {4,5,6}};
System.err.println("ref2: " + (ref2 instanceof int[][]) +
" " + (ref2 instanceof Object[]));
您应该看到如下内容:
ref2: true true
Java中的数组是协变的。这意味着TSub[]
是TSuper[]
的子类型,如果TSub
是TSuper
的子类型
您有int[][]
,它是int[]
的数组。现在,正如其他人所指出的,Java中的任何数组都是Object
的子类型,因此int[]
是Object
的子类型。因此,由于数组协方差,int[][]
是Object[]
的子类型(在上述协方差定义中,替换为TSub=int[]
和TSuper=Object
)
强>编辑< /强> -以明确为什么协方差在这里是重要的,考虑用<代码>列表 >做同样的事情是不起作用的:
List<Object> ref2 = new List<int[]>()
List ref2=新列表()
当我们分配
Object[] ref=new int[]{1,2,3};
Object[] ref2=new int[][]{{1,2,3},{4,5,6}};
Object[] ref=new int[]{1,2,3};
编译器抱怨
这是因为int
不是对象的子类型,int.class.getSuperclass()
返回null
。请记住,在Java中,基本值(整数、长整数、双精度等)不是对象
因此,二维数组似乎扩展了对象[]。
但当我打印它的超类名称时:
System.out.println(ref2.getClass().getSuperclass().getName());
System.out.println(ref2.getClass().getSuperclass().getName());
我得到了java.lang.Object
数组更像接口,因为它们执行多重继承。但从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
措辞比我的回答更恰当+1@mmyers:+1因为删除了你的答案,而选择了一个你认为更好(或者更好更快)的答案。我希望我们中有更多人这样做!如果我们继续说int[][]是一个对象[][],那么它是java语言中的一种功能,并且这些数组没有类层次结构。-1您的解释令人困惑-int
不是直接从Object
继承的-int[](int数组)是。