举个例子,如下:
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()方法