1

What us the difference between int[][] a = new int[2][3] and int a[][] = new int[][]{{11,12},{13,14,15}}?

I decompiled the .class file and found in the first case, the JVM will use multianwearray to create the array, while in the second case, it will use anewarray.

I think in the first case, JVM will create a continuous space. Am I right?

first case (int[][] a = new int[2][3])

second case (int[][] a = new int[][]{{11,12},{13,14,15}})

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
hah hah
  • 15
  • 2
  • 4
    There's no difference between `int[][] a` and `int a[][]`. However, there is a difference between `new int[2][3]` and `new int[][]{{11,12},{13,14,15}}`. The latter actually populates the array with non-default values; it also gives you an array whose "inner" arrays are not all of the same length, unlike the former. – Slaw Nov 21 '21 at 08:00
  • 1
    Note that C-style arrays are considered legacy and are not supported in most new features anymore. For example `record`s dont support them. – Zabuzard Nov 21 '21 at 13:17
  • _"create a continuous space"_ What do you mean with this? – Mark Rotteveel Nov 21 '21 at 13:18
  • @Zabuzard What do you mean `record`s don't support C-style arrays? – Slaw Nov 21 '21 at 18:30
  • 1
    @Slaw That they dont compile. See here: https://stackoverflow.com/questions/69056728/c-style-arrays-do-not-work-with-records-anymore/69056729#69056729 It also has a comment by Brian Goetz, confirming that it is a legacy feature that is faded out on new constructs. – Zabuzard Nov 22 '21 at 08:07
  • @Zabuzard Ah, you meant in the component declarations. When I was testing it out, I only tried creating arrays of the record itself (using C-style), and it was still compiling. – Slaw Nov 22 '21 at 16:29

2 Answers2

1

I think in the first case, jvm will create a continuous space. Am i right?

No. A multidimensional array is still an array of arrays. And it must be so, because the code that later accesses the array doesn't know how it was created.

Writing

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

allocates the same amount of heap space and the data on the heap has the same structure as if you would write

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

except that the code for the first variant is embedded in the JVM:

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

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);
  }
}
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
1

First Case

Creates an array of 2 int arrays, which are of length 3, which are filled with 0s.

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

Second Case

Creates a "jagged" array containing { 11, 13 }, and { 13, 14, 15 }. And which contained values are themselves array of ints.

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