일단 사전적 의미에 대해서 

 

깊은 복사(Deep Copy) : '실제 값'을 새로운 메모리 공간에 복사

(B를 A로 DeepCopy 한 후 B의 값을 변경해도 A에 반영되지 않음)

 

얕은 복사(Shallow Copy): '주소 값'을 복사 

(B에서 A로 ShalowCopy 한 후 B의 값을 변경시 B는 A의 주소값을 참조하기 때문에 A의 값도 변경)

 

코드로 확인해보기 

exp origin = new exp("코태풍",24);
exp shallowCopy = origin;
//얕은 복사 테스트
System.out.println("gd");
System.out.println(origin);
System.out.println(shallowCopy);
origin.printInfo();
shallowCopy.printInfo();

결과 

src.exp@4eec7777
src.exp@4eec7777
이름:코태풍나이:24
이름:코태풍나이:24

 

주소값이 같은것을 확인할 수 있다. 

좀 더 자세히 알아보기 위해 shalloCopy 객체의 이름과 나이를 변경해보고 다시 출력해보자 

 

shallowCopy.setName("김태풍");
shallowCopy.setAge(2);
System.out.println(origin);
System.out.println(shallowCopy);
origin.printInfo();
shallowCopy.printInfo();

결과 

src.exp@4eec7777
src.exp@4eec7777
이름:김태풍나이:2
이름:김태풍나이:2

 

어라라? shallowCopy만 변경했지만  둘 다 바뀜?  

그림으로 알아보자 

우선 메모리의 구조를 알아봐야함

 

프로그램이 실행되기 위해서는 OS가 프로그램의 정보를 메모리에 로드해야한다, 또한 실행되는 동안 cpu가 코드를 처리하기 위해서는, 메모리가 명령어와 데이터들을 저장해야한다. 

- 프로그램이 OS로부터 할당받는 대표적인 메모리공간-

 

코드 영역 - 내가 통합개발환경 인텔리제이로 입력된 코드들이 저장되는 영역 ->text 영역이라고도 함 

시작하고 종료될 때 까지 메모리에 계속 남음

 

데이터 영역- 전역변수, 정적변수가 저장되는 영역 

프로그램 시작과 함께 할당, 종료시 소멸

 

힙 영역 - 내가 직접 공간을 할당, 해제하는 메모리공간 

위와 같이 new 연산자를 통해 새로운 객체 exp를 만들어 메모리를 할당  

실제값이 저장됌 

 

스텍 영역-  프로그램이 자동으로 사용하는 임시 메모리 영역 함수 호출시 생성되는 지역변수와 매개 변수가 저장되는 영역으로 함수 호출이 완료되면 사라진다. 참조값이 저장됌 

 

자 말로 풀어쓰자면 힙 영역에 new연산자를 통해 동적할당이 됌 그리고 스텍 영역에서는 이 값을 가르키는 참조값이 존재함 말그대로 힙 영역에있는 실제값을 참조하는것이라고 보면 되겠다. shalloCopy는 stack영역에 새로운 값을 생성하는데 이 참조값도 heap에있는 origin이 가르키는 실제값이랑 같은 것을 참조함. 

 

결국 실제값을 가르키는 stack영역에서 실제값을 변경하면 그 실제값을 가르키는 참조값들의 실제값이 모두 바뀐다는 이말입니다.. 

 

 

이제 DeepCopy에 대해서 

두 가지 방법이 있음

1.new 연산자를 통해 새롭게 동적할당 한 후 속성들 모두 복사하기!  

2.Java에서 인터페이스 Cloneable을 사용해 재정의 해주기 

 

1번은 말 그대로 하면 되기에 2번방법을 코드로 보여드림

 

public class exp implements Cloneable{
    String name;
    int age;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    public exp(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String name() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int age() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public void printInfo(){
        System.out.println("이름:" +this.name() + "나이:" + this.age());
    }

exp 클래스에 인터페이스 선언 후 재정의 해주기 

 

다시 main문으로

 

exp origin = new exp("코태풍",24);
exp deepCopy = (exp) origin.clone();
//얕은 복사 테스트
System.out.println("gd");
System.out.println(origin);
System.out.println(deepCopy);

deepCopy.setName("김태풍");
deepCopy.setAge(2);
origin.printInfo();
deepCopy.printInfo();

 

결과 

src.exp@4eec7777
src.exp@3b07d329
이름:코태풍나이:24
이름:김태풍나이:2

 

그러면 deepCopy만 쓰면 되는데 왜 굳이 전부 다 바뀌어버릴 수 있는 shallowCopy가 존재하는가? 

장 단점을 알아보아요~ 

 

얕은복사

  • 장점: 같은 객체를 공유하므로 메모리를 절약하고, 빠른 장점이 존재한다. 참조에 의한 호출(Call By Reference)에서 얕은 복사가 이루어 지는 이유 중 하나이기도 하다.
  • 단점: 두 개 이상의 객체가 같은 대상을 가르키고 있기 때문에, 의도치 않게 여러 개의 객체가 동시에 수정될 수 있다.

 

깊은복사 

  • 장점: 여러 객체가 동시에 수정되는 일이 발생하지 않아, 변경에는 안전하다.
  • 단점: 객체 생성 비용이 비싸며, 메모리를 많이 점유한다.

 

이렇게 깊은복사 얕은복사를 다시 공부해보았음. 운영체제를 배우지 않아 메모리구조 이해가 힘들었음. 

메모리 구조 공부하기 ! 

 

 

참고자료

https://kyhyuk.tistory.com/182

https://zzang9ha.tistory.com/372

'3-2 > Java and Android' 카테고리의 다른 글

[Java] Generics..  (0) 2022.10.13
[Java] String 핵심 메소드  (0) 2022.09.25
[Java] 컬렉션 프레임워크 핵심 method들  (0) 2022.09.22
[안드로이드] View에 관해서  (0) 2022.09.18
[Java] Compile Err 와 Runtime Err  (0) 2022.09.10

+ Recent posts