举个例子,如下:
public void t() { String[][] a = new String[][] { { "x", "y" } }; String[] b = new String[10]; String[] c = new String[] { "x", "y" }; String[] d = { "x", "y" }; }
其中a如下语句生成的class内容一样,如下:
String[][] a2 = { { "x", "y" } };
当在创建时初始化数组时,不能指定数组的大小,如下会报错:
String[] c = new String[2] { "x", "y" }; String[][] a1 = new String[2][] { { "x", "y" } };
Eclipse编译器报错:Cannot define dimension expressions when an array initializer is provided
则生成的class内容如下:
public void t(); flags: ACC_PUBLIC Code: stack=7, locals=5, args_size=1 // 创建第一个数组 0: iconst_1 // 创建的一维数组的长度,这是因为初始化模块中只有一个元素,即{"x","y"} 1: anewarray #2 // class "[Ljava/lang/String;" 4: dup 5: iconst_0 // 表示二维数组的第0个索引上要放入一维数组值 6: iconst_2 // 由于一维数组{"x","y"}的长度为2,所以加载常量2 7: anewarray #3 // class java/lang/String 10: dup 11: iconst_0 // 在一维数组索引0的位置存储x 12: ldc #4 // String x 14: aastore 15: dup 16: iconst_1 // 在一维数组索引1的位置存储y 17: ldc #5 // String y 19: aastore 20: aastore 21: astore_1 // 创建第二个数组 22: bipush 10 24: anewarray #3 // class java/lang/String 27: astore_2 // 创建第三个数组 28: iconst_2 29: anewarray #3 // class java/lang/String 32: dup 33: iconst_0 34: ldc #4 // String x 36: aastore 37: dup 38: iconst_1 39: ldc #5 // String y 41: aastore 42: astore_3 // 创建第四个数组 43: iconst_2 44: anewarray #3 // class java/lang/String 47: dup 48: iconst_0 49: ldc #4 // String x 51: aastore 52: dup 53: iconst_1 54: ldc #5 // String y 56: aastore 57: astore 4 59: return
首先来详细分析第一个数组的创建过程:
0: iconst_1 1: anewarray #2 // class "[Ljava/lang/String;" 4: dup 5: iconst_0 6: iconst_2 7: anewarray #3 // class java/lang/String 10: dup 11: iconst_0 12: ldc #4 // String x 14: aastore 15: dup 16: iconst_1 17: ldc #5 // String y 19: aastore 20: aastore 21: astore_1
第一个数组的树形结构如下:
具体执行过程如下:
0: iconst_1
调用ImmediateItem(1)的load方法将常数加载到操作栈中
1: anewarray #2 // class "[Ljava/lang/String;"
将一维数组类型存入到常量池中,直接向操作栈中压入这个数组类型String[]
4: dup
生成一个StackItem(Object)并调用其duplicate()方法
5: iconst_0
调用ImmediateItem(0)的load方法将常数加载到操作栈中
6: iconst_2
调用ImmediateItem(2)的load方法将常数加载到操作栈中
7: anewarray #3 // class java/lang/String
将String类型存入到常量池中,直接向操作栈中压入这个类型String
10: dup
生成一个StackItem(Object)并调用其duplicate()方法
11: iconst_0
调用ImmediateItem(0)的load方法将常数加载到操作栈中
12: ldc #4 // String x
调用ImmediateItem("x")的load方法将常数加载到操作栈中
14: aastore
创建并调用IndexedItem(object)并调用其store()方法
15: dup
16: iconst_1
17: ldc #5 // String y
19: aastore
20: aastore
为如下的执行代码返回StackItem(object)
21: astore_1
创建并调用IndexedItem(object)并调用其store()方法