본문 바로가기
개발/JAVA

[JAVA] 객체 복제(clone)와 Shallow Copy, Deep Copy

by zuzuu 2022. 2. 16.
반응형

 

객체를 복제하기 위해서는 Cloneable을 구현하고, clone() 메소드를 오버라이드하면 되서 간단하다!

@Getter
@Setter
public class Person implements Cloneable{
	
	private String name;
	
	private int age;
	
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

}

 

그리고 아래와 같이 person1.clone(); 을 사용하여 person1의 객체를 복제하였다.

Person person1 = new Person();
person1.setName("홍길동");
person1.setAge(30);
		
try {
    Person person2 = (Person)person1.clone();
} catch (CloneNotSupportedException e) {
    e.printStackTrace();
}

clone()으로 객체를 복제하는 것은 Deep Copy(깊은 복제)로 새로운 메모리 공간에 객체가 생성된다.

즉, 서로 다른 객체를 참조하기 때문에 원본을 변경해도 복제본이 영향을 받지 않는다. 

 


자바에선 Shallow CopyDeep Copy가 있는데 그 차이가 뭔지 알아보자.

Shallow Copy(얕은 복제)는 원본과 복제본이 같은 객체를 공유하므로 완전한 복제라 보기 어렵다. (= 연산자 사용)

즉, 값이 아닌 주소값을 복사하고, 원본을 변경하게 되면 복제본도 영향을 받게 된다.

 

아래 예제를 살펴보면 Shallow Copy한 person3는 person1의 데이터가 변경되니 영향을 받았고, Deep Copy한 person2는 영향을 받지 않은 것을 볼 수 있다.

Person person1 = new Person();
person1.setName("홍길동");
person1.setAge(30);

Person person2 = null;
try {
	//Deep Copy
	person2 = (Person)person1.clone();
} catch (CloneNotSupportedException e) {
	e.printStackTrace();
}

//Shallow Copy
Person person3 = person1;

System.out.println(person1.getName()); //홍길동
System.out.println(person2.getName()); //홍길동
System.out.println(person3.getName()); //홍길동

//person1의 이름 변경
person1.setName("아무개");

System.out.println(person1.getName()); //아무개
System.out.println(person2.getName()); //홍길동
System.out.println(person3.getName()); //아무개

 

 

그리고 각 객체의 해시코드를 출력해보면 person1과 person3는 동일한 결과가 나오는 것을 확인할 수 있다.

System.out.println(person1.hashCode()); //903470137
System.out.println(person2.hashCode()); //1913208269
System.out.println(person3.hashCode()); //903470137

 

본인은 환경설정 정보를 담은 객체의 변경을 막고자 해당 객체를 넘길때 Deep Copy(clone)을 이용하여 복제된 객체를 넘겼고, 원본 데이터가 변경되지 않도록 하였다.

 

728x90
반응형

댓글