Note that new int[2][4] is an array of int[]; the int[] arrays in the int[][] array are all initially the same length, but there's no requirement that they remain the same length. Any element of the int[][] array can be reassigned an int[] with a different length without affecting the other elements at all. The concept of "rows" and "columns" is a higher-level idea that is not supported by Java arrays.
Using an ArrayList as other answers suggest isn't going to change this. Furthermore, Depending on how you use ArrayList, you may end up with considerable overhead due to autoboxing of int values as Integer objects.
If you want to preserve the rectangular shape of your data, I suggest that you define a Matrix class that keeps all the dimensions consistent. (Or, perhaps better, linearizes the two-dimensional array into a one-dimensional array and does the appropriate subscripting calculations using internally stored row and column sizes. Or, perhaps best, use a well-written matrix library such as JAMA or a primitive collections library like Trove.)
EDIT Here's the start of a simple matrix class that uses a linear storage scheme internally and allows matrix resizing. The data are stored in row-major order and indexing is based at 0.
public class IntMatrix {
    private int rows;
    private int cols;
    private int[] data;
    /**
     * Allocate a matrix with the indicated initial dimensions.
     * @param cols The column (horizontal or x) dimension for the matrix
     * @param rows The row (vertical or y) dimension for the matrix
     */
    public IntMatrix(int cols, int rows) {
        this.rows = rows;
        this.cols = cols;
        data = new int[cols * rows];
    }
    /**
     * Calculates the index of the indicated row and column for
     * a matrix with the indicated width. This uses row-major ordering
     * of the matrix elements.
     * <p>
     * Note that this is a static method so that it can be used independent
     * of any particular data instance.
     * @param col The column index of the desired element
     * @param row The row index of the desired element
     * @param width The width of the matrix
     */
    private static int getIndex(int col, int row, int width) {
        return row * width + col;
    }
    public int get(int col, int row) {
        return data[getIndex(col, row, cols)];
    }
    public void set(int col, int row, int value) {
        data[getIndex(col, row, cols)] = value;
    }
    /**
     * Resizes the matrix. The values in the current matrix are placed
     * at the top-left corner of the new matrix. In each dimension, if
     * the new size is smaller than the current size, the data are
     * truncated; if the new size is larger, the remainder of the values
     * are set to 0.
     * @param cols The new column (horizontal) dimension for the matrix
     * @param rows The new row (vertical) dimension for the matrix
     */
    public void resize(int cols, int rows) {
        int [] newData = new int[cols * rows];
        int colsToCopy = Math.min(cols, this.cols);
        int rowsToCopy = Math.min(rows, this.rows);
        for (int i = 0; i < rowsToCopy; ++i) {
            int oldRowStart = getIndex(0, i, this.cols);
            int newRowStart = getIndex(0, i, cols);
            System.arraycopy(data, oldRowStart, newData, newRowStart,
                colsToCopy
            );
        }
        data = newData;
    }
    . . .
}