본문으로 바로가기

디자인패턴-얕은복사&깊은복사

category 프로그래밍 언어/Java 2019. 8. 26. 18:34

얕은복사&깊은복사

얕은 복사는 말 그대로 인스턴스를 그대로 주소를 이용해서 복사해줍니다. 따라서 값을 변경하더라도 

인스턴스와 복사된 인스턴스는 같은 값을 가지게 됩니다.

깊은 복사는 말 그대로 주소를 통한 복사가 아닌 인스턴스의 값을 복사해줍니다. 전 게시글에서 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