ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JAVA 뽀개기) 얕은 복사? 깊은 복사?
    프로그래밍 언어/Java 2023. 12. 13. 12:44

    자바에서는 변수 값을 저장할 때 두 가지 형태가 있습니다!

     

    첫번째는 값을 그대로 저장하고 불러오는 형태(기본형 타입: int, long, char...)

    두번째는 값을 저장하고 저장된 곳의 주소를 가져오는 형태(참조형 타입: 배열, 클래스...)

     

    이렇게 글로만 적으면 잘 와닿지 않을겁니다! 

    그렇다면 아래의 예시코드를 보면서 확인해봅시다.

    // 얕은 복사
    int[] a = {1, 2, 3};
    int[] b = a;
    
    b[0] = 10;
    
    System.out.println(a[0]); // 10으로 출력

     

    위의 코드는 대표적인 참조형 타입인 배열을 예시로 들었습니다. 

    배열 a 는 {1, 2, 3}을 포함하고

    배열 b는 배열 a와 같게끔 =부호를 넣었습니다.

     

    이제 머리속으로 생각해 봅시다!

    배열 a는 {1, 2, 3}

    배열 a를 복사한 배열 b도 {1, 2, 3}

     

    잘 따라오셨나요?

     

    그리고 이제 배열 b의 첫번째 값을 10으로 바꿉니다.

    자, 이제 배열 b는 {10, 2, 3}의 값을 가질 겁니다. 

     

    그리고 배열 a는 {1, 2, 3}일 겁니다. 당연하겠지만 우리는 a배열 값을 바꾼게 아니죠?

     

    하지만!!!!

    결과는 b[0]을 바꾼 것만으로도 a[0]에도 영향을 미쳤습니다.

     

    이것이 JAVA의 얕은 복사입니다. 

     

    얕은 복사란, 주소값만 복사하고 실제값은 1개만 존재하는 복사입니다.

    다시말해서, 배열 a와 배열 b는 실제값을 가진 곳의 주소값을 가진 것입니다.

    그래서 배열 b의 실제값을 건드리면 배열 a의 실제값도 바뀌게 되는 것이죠! 왜냐하면 두 배열은 주소값만 가지고 있기 때문에!

     

    그렇다면 우리는 배열을 완전히 복사하지 못하는 걸까요?

    아닙니다

    이런 얕은 복사를 극복하기위해 깊은 복사란 방법이 있습니다. 

    깊은 복사는 참조형 타입의 값을 새로운 메모리 공간에서 완전히 복사하는 방법입니다.

     

    깊은 복사의 방법은 

    • 반복문 사용
    • clone 메서드 사용
    • Arrays.copyOf() 메서드 사용

    아래의 예시를 보면서 이번 포스팅 마무리하겠습니다.

    // 1. 반복문을 사용한 깊은 복사
    int[] a = {1, 2, 3};
    int[] b = new int[a.length];
    
    for(int i = 0; i < a.length; i++) {
    	b[i] = a[i];
    }
    
    b[0] = 10;
    
    System.out.println(a[0]); // 1
    System.out.println(b[0]); // 10
    
    // 2. clone을 사용한 깊은 복사
    int[] a = {1, 2, 3};
    int[] b = a.clone();
    
    b[0] = 10;
    
    System.out.println(a[0]); // 1
    System.out.println(b[0]); // 10
    
    // 3. Arrays.copyOf()를 사용한 깊은 복사
    int[] a = {1, 2, 3};
    int[] b = Arrays.copyOf(a, a.length); // 첫번째 인자로 복사할 a배열, 두번째 인자로 a배열의 길이
    
    b[0] = 10;
    
    System.out.println(a[0]); // 1
    System.out.println(b[0]); // 10
Designed by Tistory.