배열은 동일한 자료형을 묶어서 저장하는 참조 자료형이다. 생성할 때 크기를 지정해야 하고, 한 번 크기를 지정하면 절대 변
경할 수 없는 특징이 있다.
배열을 선언하면 스택 메모리에 변수의 공간만 생성하고, 공간 안은 비운 채로 둔다. 아직 배열의 실제 데이터인 객체를 생성하지 않았기 때문이다. 스택 메모리에 위치하고 있는 참조 자료형 변수의 빈 공간을 초기화할 때는 null 값을 사용할 수 있다. null 값은 힙 메모리의 위치를 가리키고 있지 않다는 의미이다. 즉, 연결된 실제 데이터가 없다는 것을 의미한다.
int[] a = new int[2]
위 코드를 자세히 살펴보자. int[]는 int 자료형만을 저장할 수 있는 배열을 의미한다. a는 참조 변수로, 실제 데이터 값을 저장하는 것이 아니라 실제 데이터값의 위칫값을 저장한다. new 키워드는 힙 메모리에 객체를 넣으라는 의미이고, int[2]는 정수 2개를 저장할 수 있는 공간을 만들라는 의미이다. 이를 정리하면 'int 자료형 2개를 저장할 수 있는 공간을 힙 메모리에 넣어 두고 어디에 넣었는지를 참조 변수 a에 저장하라'는 의미인 것이다.
여기서 알고 넘어가야 할 점이 두가지가 있다. 첫번째는 강제 초기화이다. 스택 메모리 공간은 값을 초기화하지 않으면 빈 공간으로 존재하므로 해당 변수를 출력하면 오류가 발생한다. 하지만 힙 메모리 공간은 어떤 상황에서도 빈 공간이 존재하지 않는다. 그래서 값을 주지 않으면 컴파일러가 값을 강제로 초기화한다. 강제 초기화는 자료형에 따라 다른데, 기본 자료형일 때 숫자는 모두 0(실수는 0.0), 불리언은 false로 값이 초기화되며 이외의 모든 참조 자료형은 null로 초기화된다.
두번째는 복사할 때 무엇이 복사되는지이다. 대입 연산자(=)를 이용해 변수가 복사하는 것은 변수에 포함되어 있는 스택 메모리의 값을 복사한다는 것이다. 그런데 기본 자료형과 참조 자료형은 스택 메모리에 저장하는 값의 의미가 다르므로 복사할 때도 차이가 생긴다.
//기본 자료형의 경우
int a = 3;
int b = a;
b = 5;
System.out.println(a); // 3
System.out.println(b); // 5
//참조 자료형의 경우
int[] a = {2, 3};
int[] b = a;
b[1] = 5;
System.out.println(a[1]); // 5
System.out.println(b[1]); // 5
먼저 기본 자료형을 살펴보면, 기본 자료형은 스택 메모리에 실제 데이터값을 저장하므로 기본 자료형 변수를 복사하면 실제 데이터값이 1개 더 복사된다. 이후 복사된 값을 아무리 변경해도 원본 값은 영향을 받지 않는다.
이어서 참조 자료형을 살펴보면, 참조 자료형은 스택 메모리에 실제 데이터값이 아닌 힙 메모리에 저장된 객체의 위치를 저장하고 있따. 따라서 참조 자료형 변수를 복사하면 실제 데이터가 복사되는 것이 아니라 실제 데이터의 위칫값이 복사된다. 따라서 하나의 참조 변수를 이용해 데이터를 수정하면 다른 참조 변수가 가리키는 데이터도 변하게 된다.
Reference
- 자바 완전 정복 | 김동형 지음
댓글