[Java] 자바 ThinClone을 통해서 클래스를 복사해보자!

2021-01-19


기존에 변수나 배열과 같은 경우에는 새로운 객체를 만들어서 복사를 진행하면 된다. 그러면 클래스를 복사해서 사용하고자 하면 어떻게 해야 할까? ctrl + c -> ctrl + v를 사용해서 새로운 클래스를 만들어 사용하면 될까?라고 생각할 수 도 있지만 자바 자체에서 이와 같은 고민을 해결해주기 위해 Cloneable이라는 인터페이스를 제공한다. 즉 복사를 하고자 하는 클래스에 implements Cloneable를 붙여주면 이와 같은 클래스를 사용할 수 있다. 바로 코드를 살펴보자.

 


package tThinClone.copy;

import java.util.Arrays;

public class People implements Cloneable {
	String name;
	int age;
	
	public People(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public People copyPeople() {
		People cloneP = null;
		try {
			cloneP = (People) clone();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return cloneP;
	}
	
	
}

 

예제로 사용할 코드는 People이다 필드로는 name / age 를 가지고 있으며, 초기화할 수 있도록 생성자도 하나 만들어 주었다. 메서드는 복사를 진행하기 위한 copyPeople를 하나 만들어 주었다. 복사를 진행하기 전 미리 People 객체를 하나 만들어 null을 넣어주고 이후 try / catch 구문을 이용해 복사하고자 하는 객체를 감싸주면 된다. 여기서 복사가 진행되는 clone() 메서드는 Object 클래스의 메서드이며 리턴 값 역시 Object이기 때문에 (People)로 강제 형변환을 진행해 주어야 한다. try / catch구문으로 감싸주는 이유는 Cloneable인터페이스를 구현하지 않으면, CloneNotSupportedException이 발생할 수 있기 때문이다.


이제 메인클래스로가 실제 복사가 정상적으로 진행되는지 알아보자. (제대로 될 경우 복사된 클래스의 필드 내용 변경 시 원본 클래스의 데이터는 안전하게 보존이 되어야 한다.)

package tThinClone.copy;

public class main {

	public static void main(String[] args) {
			
		People people = new People("abc", 25);
		
		People cloneP = people.copyPeople();
		
		cloneP.name = "abb";
		cloneP.age = 35;
		
		
		System.out.println("복제된 학생의 이름은 = " + cloneP.name);
		System.out.println("복제된 학생의 나이는 = " + cloneP.age);
		
		System.out.println("-------------------------------------------------------------------------------");
		
		System.out.println("복제된 학생의 이름은 = " + people.name);
		System.out.println("복제된 학생의 나이는 = " + people.age);
		
		
		//얇은 복제를 통해 단순 필드값만 복제되어 원본데이터의 필드값 변경없이 안전하게 관리되는 것을 확인할 수 있다.
		//유지하는 것을 확인할 수 있다.
		
	}

}

 

원본 데이터의 name은 abc age는 25 값을 주고 이후 복사된 클래스의 데이터는 name abb / age 35로 변경된 값을 주었다. 해당 결과가 어떻게 나오는지 콘솔 값을 살펴보자.

이와 같이 원본 데이터는 변경되지 않고 복사된 클래스의 내용만 변경되어 출력되는 것을 확인할 수 있다. 

 

다만 여기서 중요한 점이 있다. 얇은 복제는 단순한 필드 값을 복사할 때만 사용하는 것이 좋다. 그 이유는 참조 타입을 얇은 복제 시 같은 참조 번지도 같이 복사되기 때문에 복사된 클래스를 변경하면 원본 객체도 변경되게 된다. 이와 같은 경우에는 깊은 복제 DeepClone를 진행해야 하는데 이는 다음에 알아보도록 하자.