java数组如何真正起作用

Seb*_*ber 3 java arrays jvm scjp runtime

有人可以解释一下阵列在Java中是如何工作的.

我对以下代码感到惊讶:

        Object test = new Object[2][2];
        Object test2 = new Object[] {
                new Object[2],new Object[2]
        };
        Object test3 = new Object[2][];
        ((Object[])test3)[0] = new Object[2];
        ((Object[])test3)[1] = new Object[2];
        System.out.println(test instanceof Object[]);
        System.out.println(test instanceof Object[][]);
        System.out.println(test2 instanceof Object[]);
        System.out.println(test2 instanceof Object[][]);
        System.out.println(test3 instanceof Object[]);
        System.out.println(test3 instanceof Object[][]);
Run Code Online (Sandbox Code Playgroud)

只有test2不是Object [] []的实例

运行时有什么区别?

编辑:我看到一些答案.Jon Skeet,请注意我能做到:

Object[] test4 = (Object [])test;
test4[0] = "blaaa";
test4[1] = "toto";
System.out.println(test4);
Run Code Online (Sandbox Code Playgroud)

test instanceof Object []返回true,并且在转换时没有在运行时引发异常.根据SCJP的Sierra&Bates一书,测试IS-A Object [] []还有一个Object []

但是当试图用"test4 [0] ="blaaa";"重新分配一个新值时,我得到一个异常:线程中的异常"main"java.lang.ArrayStoreException:Main.main中的java.lang.String(Main. Java的:24)

所以在运行时看来,test和test2都是IS-A Object [],并且都包含对象数组,但只有一个是IS-A Object [] []

Jea*_*rin 12

Test2仅被声明为对象数组.它包含的对象恰好也是数组,但是没有声明.这就是区别.


Jon*_*eet 8

test2指的是两个元素的数组.它的类型只是Object[]- 所以这些元素可以引用任何对象.特别是,您可以写:

// Valid
Object[] foo = (Object[]) test2;
foo[0] = "hello";
Run Code Online (Sandbox Code Playgroud)

而那不适用于test:

// Invalid - test isn't just an Object[], it's an Object[][]
Object[] foo = (Object[]) test;
test[0] = "hello";
Run Code Online (Sandbox Code Playgroud)

因为test引用的数组的元素类型Object[]不是Object.数组"知道"每个元素应为null或对a的引用Object[],因此VM将阻止它存储字符串.

你可以转换test为一个Object[]你可以转换为a String[]的方式Object[]- 这就是所谓的数组协方差,在我看来允许它是错误的.正如我们所见,VM必须在执行时检查商店.