일단 사전적 의미에 대해서
깊은 복사(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)에서 얕은 복사가 이루어 지는 이유 중 하나이기도 하다.
- 단점: 두 개 이상의 객체가 같은 대상을 가르키고 있기 때문에, 의도치 않게 여러 개의 객체가 동시에 수정될 수 있다.
깊은복사
- 장점: 여러 객체가 동시에 수정되는 일이 발생하지 않아, 변경에는 안전하다.
- 단점: 객체 생성 비용이 비싸며, 메모리를 많이 점유한다.
이렇게 깊은복사 얕은복사를 다시 공부해보았음. 운영체제를 배우지 않아 메모리구조 이해가 힘들었음.
메모리 구조 공부하기 !
참고자료
'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 |