How do 2D arrays work in Java, and what is really going on when you write int[][] grid?
Java has no true two-dimensional array type. int[][] grid declares an array whose elements are themselves arrays of int — an array of arrays, also called a ragged array structure. That has a concrete consequence: grid.length is the number of rows, and grid[0].length is the number of columns in the first row, but nothing forces the other rows to have the same length.
When you write new int[3][4], the JVM allocates one array of three references and then three separate int arrays of four elements each. The rows are entirely independent objects. Writing grid[1][2] = 7 reaches into the second row object; nothing is shared with the first row.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[][] grid = new int[3][4]; // 3 rows, 4 columns
System.out.println("rows : " + grid.length);
System.out.println("columns in row 0: " + grid[0].length);
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
grid[r][c] = r * 10 + c;
}
}
for (int[] row : grid) {
System.out.println(Arrays.toString(row));
}
// Every row is a separate object.
System.out.println("rows are distinct: " + (grid[0] != grid[1]));
}
}Because the rows are separate objects, the inner loop must use grid[r].length rather than a hard-coded column count. That is exactly what makes jagged arrays possible: you can build rows of different lengths, and the idiomatic traversal still works because each row knows its own size.
One memory point: the outer array holds references, so a 2D array of a million cells is a million ints plus a handful of row objects. If you need a genuinely rectangular block of primitives with no indirection, a single flat array with a computed index is faster, and libraries like Apache Commons Math use that layout for large matrices.