为什么这段代码会编译?
Object[] object = new String[5][5];
我的意思是,如果我创建的维度不同于引用变量中指定的数组对象,为什么还能这样做?
这不编译:
String[] strings = new String[5][5];
那么这里发生了什么?
答案 0 :(得分:4)
Java中的数组是covariant。对于任何类型T1
和T2
,如果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
。
答案 1 :(得分:3)
第一个编译因为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.
答案 2 :(得分:1)
任何数组本身都是Object
。
因此,按照这条规则:
String[5]
是Object
String[5][]
是Object[]
String[5][]
和String[5]
也是Object
。
当想要强制编译器来处理数组或多数组而不是简单的Object
时,区别很重要。
对于Object
以外的所有类型,此规则不适用,然后:
String[5][5]
不是 String[]
答案 3 :(得分:1)
一个字符串数组(例如String [5])可以被视为一个Object。对于二维数组(或数组数组)也是如此。但是,字符串的二维数组不是字符串的一维数组,因此您不能将字符串的1-dim数组分配给2-Dim字符串数组。
另请注意,在Java(而不仅仅是)中,二维数组基本上是一个数组数组。因此,在您给出的示例中,您可以将一个二维数组(一个数组数组)的字符串分配给一个对象数组(所以在Object数组的每个索引处存储一个字符串的字符串数组),但是你不能用字符串来做。
答案 4 :(得分:0)
1-对于第一个代码,您无法使用字符串方法
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];