방법 ② 배열 객체의 행 성분부터 생성하고 열 성분 생성하기
두 번째 방법은 2차원 배열의 행 성분만 먼저 생성하고 각 행에 열 성분을 생성하는 것이다. 다소 복잡해 보이지만, 앞서 설명한 2차원 배열의 메모리 구조를 이해하면 쉽게 이해할 수 있을 것이다. 작성 방법과 예시는 다음과 같다.
🍉배열 객체의 행 성분부터 생성하고 열 성분 생성하기
자료형[][] 참조 변수명 = new 자료형 [행의 길이][]; // 열의 길이는 표시하지 않음
참조 변수명[0] = 1차원 배열의 생성;
참조 변수명[1] = 1차원 배열의 생성;
...
참조 변수명 [행의 길이 -1] = 1차원 배열의 생성;
예
// 1
int[][]a = new int[2][]; // 행 성분 생성
a[0] = new int[3];
a[0][0] = 1; a[0][1] = 2; a[0][2] = 3;
a[1] = new int[3];
a[1][0] = 4; a[1][1] = 5; a[1][2] = 6; // 열 성분 생성
// 2
int[][] a = new int[2][]; // 행 성분 생성
a[0] = new int[]{1, 2, 3};
a[1] = new int[]{4, 5, 6}; // 열 성분 생성
두 예시는 각 행을 구성하는 1차원 배열을 생성하는 방법에서만 차이가 난다. 먼저 2차원 배열을 생성할 때 행의 개수까지만 적고, 열의 개수는 적지 않는다. 열의 개수를 나중에 결정한다는 것이다. 여기서는 '배열의 두 번째 특징에 따라 생성할 때 크기를 지정해야 하는데, 이렇게 되면 규칙에 어긋나지 않는가?' 라고 생각할 수 있다. 하지만 그렇지 않다. 참조 변수 a가 가리키는 곳은 행의 개수만큼 메모리 공간을 차지하는 1차원 배열이기 때문이다. 즉, 참조 변수 a를 선언하고 값을 가리키게 하는 데는 행의 길이만 있으면 되는 것이다. 이러한 방법 ②를 이용해 생성되는 메모리의 구조를 살펴보면 다음과 같다.
우선 행의 개수만 정의해 2차원 배열을 생성하면 첫 번째 메로의 구조처럼 참조 변수 a가 가리키는 곳으로 갔을 때 2칸의 방이 있다. 각 원소는 기본 자료형이 아닌 참조 자료형(int[])이고, 힙 메모리는 강제 초기화되는 영역이므로 null이 들어갈 것이다.
다음으로 a[0] = new int[3]의 코드를 살펴보자. 그대로 풀어쓰면 'int형 데이터 3개를 저장할 수 있는 공간을 만들어 힙 메모리에 넣고(new int[3]) 저장한 위치 정보를 a[0]에 저장하라'는 의미이다. 아래쪽 a[1] = new int[3]도 동일한 의미다. 이후 각각의 2차원 인덱스 위치에 값을 대입한 것이 첫 번째 예제다. 두 번째 예제는 각 인덱스 위치에 값을 대입하는 방법만 다를 뿐 메모리에서 일어나는 모든 과정은 동일하다.
방법 ②를 잘 이해하면 뒤에서 배울 2차원 비정방 행렬도 쉽게 이해할 수 있다. 배열을 포함한 참조 자료형은 꼭 메모리의 구조와 함께 이해하는 것이 매우 중요하며 이것이 프로그래밍을 쉽게 이해할 수 있는 유일한 방법이다.