관리 메뉴

제뉴어리의 모든것

[Java] 얕은 복사와 깊은 복사 본문

JAVA

[Java] 얕은 복사와 깊은 복사

제뉴어리맨 2021. 4. 3. 01:15

- 얕은 복사(shallow copy)

  • 한 쪽에서 수정이 발생되면 다른쪽에도 영향을 끼쳐 같아지게 된다.
  • 가능한 이유는 얕은 복사가 주소값을 복사하기 때문에 주소로 값을 참조하여 값이 변경되면 해당 값을 참조하고 있는 배열들의 값이 변경된다.
  • 즉, 복사된 배열이나 원본 배열이 변경될 때, 함께 변경된다. = 연산자는 얕은 복사를 수행한다.

C언어에서 사용하는 포인터 개념의 복사이다.

리터럴 상수가 아닌 이상 기본적으로 객체들은 주소값을 가지고 있고, 객체 이름은 주소값을 나타낸다.

즉 일반적으로 객체에 객체를 대입하는것은 주소값을 대입하는것이고.

같은 주소를 가리킨다느것은 같은 객체를 바라보고 사용한다는것이다.

 

int[] a = new int[2];
a[0] = 2;
a[1] = 4;
int[] b = a;
b[0] = 6;
b[1] = 8;

System.out.println(a[0]+", "+a[1]);
System.out.println(b[0]+", "+b[1]);

// 결과
6, 8
6, 8

배열객체를 담을 수있는 b변수에 a배열 객체를 담았다.

즉 주소값을 넘긴것이며, a변수와 b변수는 저멀리 어떤 주소에 위치하는 데이터(객체)를 가리키는것이다.

그러므로 b를 바꾸면 a도 바뀌고 그 반대도 당연히 바뀐다.

 

- 깊은 복사(Deep copy)

  • 깊은 복사는 주소값을 참조하는 것이 아닌, 새로운 메모리 공간에 값을 복사하는 것이기 때문에 원본 배열이 변경되어도 복사된 배열에 전혀 상관이 없다.
  • 따라서 배열을 복사한 후에 한쪽 값을 수정해도 다른 배열에 영향을 끼치지 않는다.

그냥 객체안에 값들을 통째로 복사하여 또다른 주소에 객체를 생성하여 가리키는것이다.

public static void main(String[] args) {
    int[] arr = new int[10];
    int[] copy = deepCopyWithClone(arr);
    
    for (int i = 0; i < arr.length; i++) arr[i] = i;
    for (int a : arr) System.out.print(a + " ");

    System.out.println();
    copy[0] = 100;
    for (int a : copy) System.out.print(a + " ");
}

private static int[] deepCopyWithClone(int[] original) {
    if (original == null) return null;
    int[] result = new int[original.length];

    result = original.clone();
    return result;
}

// 결과
0 1 2 3 4 5 6 7 8 9 -> arr
100 0 0 0 0 0 0 0 0 0 -> copy

중요한부분은 original.clone(); 이것 일 것이다.

original.clone(); 사용하여 그냥 값자체를 복사하여 새로 만든다.

 

출처 : [Java] 얕은 복사와 깊은 복사 - VictoryWoo (woovictory.github.io)