Java 数组是单个对象。并且分配一个新数组只能分配一个对象。分配可以嵌套,通过在数组初始化块中写入 new、自动装箱或通过对象构造函数也以链式操作的形式调用 new。
您的三个案例的答案是:1、1 和 1。下面的详细信息,以及一些突出特殊案例的其他示例。
字符串和自动装箱的整数也可以是特殊情况,因为 JVM 对它们有特殊的缓存。以下注释示例中的详细信息:
// 1 object, an array with 10 elements (set to zero)
int[] array = new int[10];
// 1 objects, an array with 10 elements (set to null)
String[] str = new String[10];
// 1 object, an array with 10 elements pointing at objects
// that have been preallocated within the String pool. See
// the appendium below for evidence.
String[] str = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
// 3 objects, one for the array and one per integer.
Integer[] a4 = new Integer[] { new Integer(1), new Integer(2) };
// 1 object again, Java has an Integer pool of limited size which is used
// to optimise auto boxing; 1 and 2 will definitely be within that default
// range
Integer[] a6 = new Integer[] { 1, 2 };
// 3 objects, the default size of the int pool is fairly low
// but it can be increased via a JVM flag.
Integer[] a5 = new Integer[] { 1000, 2000 };
// 3-5 objects -- 1 for the array, one for each of the string objects and 1
// per char array backing the string. Depending on JVM version the char
// array may be shared with the interned strings, so that one is a little tricky
// and is why I said 3-5.
String[] str = {new String("1"), new String("2")};
附录
只是为了好玩,这里是常量池的证据。
下面的 Java 代码编译成下面的字节码,注意只有数组被分配。元素使用类池常量。我已经缩短了输出,它只是为每个元素重复相同的代码(dup,iconst,ldc,aastore,...)
java代码:
String[] str = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
JVM字节码:
0: bipush 10
2: anewarray #2 // class java/lang/String
5: dup
6: iconst_0
7: ldc #3 // load constant from class pool - String 1
9: aastore // store into array
10: dup
11: iconst_1
12: ldc #4 // String 2
14: aastore
15: dup
16: iconst_2