얕은복사&깊은복사
얕은 복사는 말 그대로 인스턴스를 그대로 주소를 이용해서 복사해줍니다. 따라서 값을 변경하더라도
인스턴스와 복사된 인스턴스는 같은 값을 가지게 됩니다.
깊은 복사는 말 그대로 주소를 통한 복사가 아닌 인스턴스의 값을 복사해줍니다. 전 게시글에서 clone()을 통해서 하는 것이 깊은복사입니다.
우선 고양이를 복사하기 위해 Cat.java를 만들어줍니다.
package com.jeongchan.prototype2;
public class Cat implements Cloneable{
private String name;
private Age age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(Age age) {
this.age = age;
}
public Age getAge() {
return age;
}
//깊은복사
public Cat copy() throws CloneNotSupportedException {
Cat cat = (Cat)this.clone();
//명시적으로 깊은복사해주기.
cat.setAge(new Age(this.age.getYear(),this.age.getValue()));
return cat;
}
}
그 다음 고양이의 나이를 알기위한 Age클래스를 작성해줍니다.
package com.jeongchan.prototype2;
public class Age {
private int year;
private int value;
public Age(int year, int value) {
super();
this.year = year;
this.value = value;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
이제 Main에서 깊은 복사와 얕은 복사의 차이를 알아보도록 하겠습니다.
두 차이는 주석처리를 깊게 하였으므로 이해하는데 어려움은 없을 겁니다.
Step 1과 Step 2 코드 부분을 주석처리 하면서 확인 하시기 바랍니다.
//Cat yo = navi; // Step 1 . 얇은 복사
Cat yo = navi.copy(); //Step 2. 깊은 복사
package com.jeongchan.prototype2;
/**
* 얕은복사와 깊은복사
* @author dlwjd
*
*/
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Cat navi = new Cat();
navi.setName("나비");
navi.setAge(new Age(2018,1));
//Cat yo = navi; // Step 1 . 얇은 복사
Cat yo = navi.copy(); //Step 2. 깊은 복사
//yo의 이름 바꾸기
yo.setName("야옹");
yo.setAge(new Age(2016,3));
//여기서 만약에 yo.getAge().setYear()로 변경 해주면 깊은 복사가 안됨 이는 Cat copy()에서 처리해주어야함.
//cat.setAge(new Age(this.age.getYear(),this.age.getValue())); 를 copy()안에 추가.
//Step 1 . 그러나 둘다 야옹으로 나옴. 이는 yo가 navi를 그대로 복사하는 얕은복사이기 떄문.
//Step 2 . 깊은 복사는 navi가 가지고 있는 주소가 아니라 값을 복사하는것이 깊은 복사. 따라서 각자 값이 다르게나옴
System.out.println("navi의 이름: "+navi.getName());
System.out.println("yo의 이름: "+yo.getName());
System.out.println("navi의 나이: "+navi.getAge().getYear());
System.out.println("yo의 이름: "+yo.getAge().getYear());
}
}
얕은 복사일 경우
navi의 이름: 야옹
yo의 이름: 야옹
navi의 나이: 2016
yo의 이름: 2016
주소 자체가 복사가 되기 때문에 같은 값이 나온다는 것을 알 수 있습니다.
깊은 복사일 경우
navi의 이름: 나비
yo의 이름: 야옹
navi의 나이: 2018
yo의 이름: 2016
'프로그래밍 언어 > Java' 카테고리의 다른 글
디자인패턴 - 빌드패턴(2) (0) | 2019.08.30 |
---|---|
디자인패턴 - 빌더패턴(1) (0) | 2019.08.30 |
디자인패턴- 프로토타입 패턴 (0) | 2019.08.26 |
디자인패턴- 싱글톤 패턴 (0) | 2019.08.24 |
디자인패턴 - 전략패턴 (0) | 2019.08.23 |