为什么 "Object[] object = new String[][]" 可以编译通过?- Java

9
为什么这段代码可以编译?
Object[] object = new String[5][5];

我的意思是,如果我创建的数组对象的维度与引用变量中指定的维度不同,那么为什么我还能这样做呢?

这段代码无法编译:

String[] strings = new String[5][5];

所以这里发生了什么?

9
请记住,在Java中,数组是一个“Object”对象。 - Oliver Charlesworth
数组,在这种情况下是一个字符串数组,也被认为是对象。尝试使用Object obj = new String[],看看它的效果如何。 - Ian
5个回答

4

Java中的数组是协变的。对于任何类型的T1T2,如果T2派生自T1(即T2直接或间接扩展或实现T1),那么T2[]T1[]的子类型。因此,String[]Object[]的子类型,您可以将一个String[]类型的对象分配给Object[]类型的变量。

请注意(正如Oli Charlesworth在评论中指出的那样),协变破坏了Java的编译时类型安全性。下面这段代码:

Object [] o = new String[5];
o[0] = Integer.valueOf(3);

当第二行尝试执行时,会在运行时生成ArrayStoreException。因此我并不是在建议协变数组很棒;只是这是语言的工作方式。

关于您的第二个例子,String[]不是String[][]。协变不适用,因为String[]不派生自String。但是,您可以这样做:

Object[] o = new String[5][5];

因为一个 String[] 实际上是一个 Object

这没问题,直到你执行 String[] strings = new String[5]; Object[] objs = strings; objs[0] = new Integer(42);... - Oliver Charlesworth
@OliCharlesworth - 谢谢您。我在我的答案中添加了一些关于它的内容。 - Ted Hopp

4
第一个可以编译,因为String[]是一个Object。第二个无法编译,因为String不是String[]
Object[] object = new String[5][5];  // Means each element is an String[] which is an Object as well.

String[] strings = new String[5][5]; // Also Means each element is an String[] which is not same as just String.

1
这就是我在寻找的答案。 - GabrielBB

1
任何数组本身就是一个Object
因此,根据这个规则:
String[5] 是一个 Object
String[5][] 是一个 Object[]
String[5][]String[5] 也是 Object
当想要强制编译器处理数组或多维数组而不是简单的Object时,这种区别很重要。
对于除Object之外的所有类型,这个规则不适用,然后:
String[5][5] 不是一个 String[]

1
一个字符串数组(例如String[5])可以被视为一个对象。同样,二维数组(或数组的数组)也是如此。但是,一个由字符串组成的双重数组不是一个由字符串组成的单一数组,因此你不能将一维字符串数组分配给二维字符串数组。
同时要注意,在Java中(不仅仅是Java),二维数组基本上是一个数组的数组。因此,在你提供的示例中,你可以将一个由字符串组成的二维数组(一个数组的数组)分配给一个对象数组(因此在对象数组的每个索引处存储一个由字符串组成的单一数组),但你不能使用字符串数组这样做。

0

对于第一段代码,您将无法使用字符串方法

object[0][0].substring(1);//error
//correct to use string methods
strings[0][0].substring(1);
strings[0][0].chartAt(0);

但是第二段代码可以使用字符串方法。

2- 第二段代码必须如下:

String[][] strings = new String[5][5];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接