【问题标题】:What's the difference between these 2 array definitions?这两个数组定义有什么区别?
【发布时间】:2026-01-27 10:30:01
【问题描述】:

int[][] a = new int[2][3]int a[][] = new int[][]{{11,12},{13,14,15}} 有什么区别?

我反编译了.class文件,发现第一种情况,JVM会使用multianwearray来创建数组,而第二种情况,会使用anewarray。

我认为在第一种情况下,JVM 会创建一个连续的空间。我说的对吗?

第一种情况(int[][] a = new int[2][3]

第二种情况(int[][] a = new int[][]{{11,12},{13,14,15}}

【问题讨论】:

  • int[][] aint a[][] 之间没有区别。但是,new int[2][3]new int[][]{{11,12},{13,14,15}} 之间存在差异。后者实际上用非默认值填充数组;它还为您提供了一个数组,其“内部”数组的长度并不完全相同,与前者不同。
  • 请注意,C 风格的数组被认为是遗留的,大多数新功能不再支持。例如records 不支持它们。
  • “创造一个连续的空间”你这是什么意思?
  • @Zabuzard records 不支持 C 样式数组是什么意思?
  • @Slaw 他们不编译。见这里:*.com/questions/69056728/… 它也有 Brian Goetz 的评论,确认它是一个旧功能,在新结构中淡出。

标签: java arrays


【解决方案1】:

我认为在第一种情况下,jvm 会创建一个连续的空间。我说的对吗?

没有。多维数组仍然是数组的数组。而且一定是这样,因为后面访问数组的代码并不知道它是如何创建的。

写作

int[][] a = new int[2][3];

分配相同数量的堆空间,并且堆上的数据具有与您编写时相同的结构

int[][] a = new int[2][];
a[0] = new int[3];
a[1] = new int[3];

除了第一个变体的代码嵌入在 JVM 中:

https://github.com/openjdk/jdk17u/blob/master/src/hotspot/share/oops/objArrayKlass.cpp#L178ff

objArrayOop array = allocate(length, CHECK_NULL);
//...
if (length != 0) {
  for (int index = 0; index < length; index++) {
    ArrayKlass* ak = ArrayKlass::cast(ld_klass);
    oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
    h_array->obj_at_put(index, sub_array);
  }
}

【讨论】:

    【解决方案2】:

    第一种情况

    创建一个由 2 个 int 数组组成的数组,它们的长度为 3,用 0s 填充。

            | [ ][0] | [ ][1] | [ ][2] 
     [0][ ] |    0   |    0   |    0
     [1][ ] |    0   |    0   |    0
    

    第二种情况

    创建一个包含{ 11, 13 }{ 13, 14, 15 } 的“锯齿形”数组。其中包含的值本身就是ints 的数组。

            | [ ][0] | [ ][1] | [ ][2] 
     [0][ ] |   11   |   12   |  error
     [1][ ] |   13   |   14   |   15
    

    【讨论】: