Instinctively one thinks geometrically: horizontal (X) axis and then vertical (Y) axis. This is not, however, the case with a 2D array, rows come first and then columns.
Consider the following analogy: in geometry one walks to the ladder (X axis) and climbs it (Y axis). Conversely, in Java one descends the ladder (rows) and walks away (columns).
Java specifies arrays similar to that of a "row major" configuration, meaning that it indexes rows first. This is because a 2D array is an "array of arrays".
For example:
int[ ][ ] a = new int[2][4]; // Two rows and four columns.
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
It can also be visualized more like this:
a[0] -> [0] [1] [2] [3]
a[1] -> [0] [1] [2] [3]
The second illustration shows the "array of arrays" aspect. The first array contains {a[0] and a[1]}, and each of those is an array containing four elements, {[0][1][2][3]}.
TL;DR summary:
Array[number of arrays][how many elements in each of those arrays]
While Matt B's may be true in one sense, it may help to think of Java multidimensional array without thinking about geometeric matrices at all. Java multi-dim arrays are simply arrays of arrays, and each element of the first-"dimension" can be of different size from the other elements, or in fact can actually store a null "sub"-array. See comments under this question
All depends on your visualization of the array. Rows and Columns are properties of visualization (probably in your imagination) of the array, not the array itself.
It's exactly the same as asking is number "5" red or green?
I could draw it red, I could draw it greed right? Color is not an integral property of a number. In the same way representing 2D array as a grid of rows and columns is not necessary for existence of this array.
2D array has just first dimention and second dimention, everything related to visualizing those is purely your flavour.
When I have char array char[80][25], I may like to print it on console rotated so that I have 25 rows of 80 characters that fits the screen without scroll.
I'll try to provide viable example when representing 2D array as rows and columns doesn't make sense at all: Let's say I need an array of 1 000 000 000 integers. My machine has 8GB of RAM, so I have enough memory for this, but if you try executing var a = new int[1000000000], you'll most likely get OutOfMemory exception. That's because of memory fragmentation - there is no consecutive block of memory of this size. Instead you you can create 2D array 10 000 x 100 000 with your values. Logically it is 1D array, so you'd like to draw and imagine it as a single sequence of values, but due to technical implementation it is 2D.
The best way to remember if rows or columns come first would be writing a comment and mentioning it.
Java does not store a 2D Array as a table with specified rows and columns, it stores it as an array of arrays, like many other answers explain. So you can decide, if the first or second dimension is your row. You just have to read the array depending on that.
So, since I get confused by this all the time myself, I always write a comment that tells me, which dimension of the 2d Array is my row, and which is my column.
In c++ (distant, dusty memory) I think it was a little easier to look at the code and understand arrays than it is in Java sometimes. Both are row major. This illustration worked for me in helping to understand.
Given this code for a 2d array of strings...
String[][] messages;
messages = new String[][] {
{"CAT","DOG","YIN","BLACK","HIGH","DAY"},
{"kitten","puppy","yang","white","low","night"}
};
int row = messages.length;
int col = messages[0].length;
Naming my ints as if it were a 2d array (row, col) we see the values.
row = (int) 2
col = (int) 6
The last two lines of code, where we try to determine size and set them to row and col does not look all that intuitive and its not necessarily right.
What youre really dealing with here is this (note new variable names to illustrate):
int numOfArraysIn = messages.length;
int numOfElementsIn0 = messages[0].length;
int numOfElementsIn1 = messages[1].length;
Where messages.length tells you messages holds two arrays. An array of arrays.
AND then messages[x].length yields the size of each of the individual arrays 01 inside messages.