본문 바로가기

[Kotlin&Spring] 5기 내일배움캠프

[Kotlin&Spring] 5기 얕은 복사와 깊은 복사 - 배열(Array)

오늘은 강의 중에 있었던 배열의 앝은 복사와 깊은 복사에 대해 알아보고자 한다

 

자바에서 배열(Array)는 참조형(Reference) 타입으로 힙(heap) 메모리에 저장된다

그리고 배열의 변수명과 배열의 메모리 번지는 스택(stack) 메모리에 저장된다

이러한 특징 때문에 배열을 복사할 때 얕은 복사과 깊은 복사가 이루어진다

 

얕은 복사는 메모리 번지만 복사되는 것을 말한다

int[] a = {1, 2, 3, 4};
int[] b = a;

 

위의 코드는 대표적인 배열의 얕은 복사이다

이 경우에 배열 a, b는 모두 같은 메모리에 대한 주소를 가진다

따라서 값은 하나인데 a, b 두 곳에서 참조를 하기 때문에 둘 중 하나의 값이 변경되면 다른 변수의 값에도 반영된다

얕은 복사를 하는 이유는 단순히 참조를 하기 위해서이다

 

깊은 복사라는 복사 방법이 있는데 이는 먼저 있던 객체의 값을 유지한 채 새로운 값을 생성해 수정을 하기 위함이다

깊은 복사는 여러 방법이 있는데 다음은 똑같은 길이를 가진 새로운 배열을 new 키워드로 생성하고 값을 하나씩 넣는 방법이다

int[] a = {1, 2, 3, 4};
int[] b = new int[4];
int[] var = new int[a.length];//배열 a의 길이 파악 어려울 때

for (int i = 0; i < a.length; i++) {
    b[i] = a[i];
}

 

위 방식을 통해 a 배열과 똑같은 값을 갖지만 메모리 주소가 다른 b 배열을 가질 수 있다

배열을 깊은 복사하는 방법은 위 방식 외에도 Java에서 제공하는 Object 클래스와 Arrays 클래스의 메소드를 사용해서 가능하다

int[] a = {1, 2, 3, 4};
int[] b = a.clone();

 

위 클래스는 Object 의 clone 메소드를 사용해 깊은 복사를 하고 있다

Object 클래스는 java.lang.Object 로, 다른 클래스를 상속한다고 명시하지 않은 모든 클래스를 상속받는 클래스인데, 결국에 모든 클래스가 상속하는 최상위 클래스이기 때문에 모든 클래스에서 이용할 수 있다

그러나 clone() 메소드는 1차원의 배열에서만 깊은 복사를 하고 다차원 배열에서는 얕은 복사를 한다

2, 3차원 등의 배열 복사시 순회를 돌며 하나하나 복사하다보니 성능이 저하되어 그렇다고 한다

 

그외에도 java.util.Arrays 클래스의 메소드를 사용해 깊은 복사를 할 수 있다

int[] a = {1, 2, 3, 4};
int[] b = Arrays.copyOf(a, a.length);//매개변수로 배열과 원하는 길이를 받음
int[] c = Arrays.copyOf(a, 1, 3);//매개변수로 배열과 시작점, 원하는 길이를 받음

 

다음에는 배열뿐 아니라 객체의 얕은 복사와 깊은 복사에 대해 알아봐야겠다