티스토리 뷰

리팩토링(스프링기반)

오브젝트 복제하기

까오기 까오기 2019. 1. 7. 15:06

Object를 일반적인 방법으로 복제를 하는 경우 문제가 발생할 수 있습니다. 

 

아래 예제를 통해 확인해 보겠습니다. 

테스트 코드 

public class TestClone {

 

public static void main(String[] args) {

User user1 = new User("test1");

User cUser1 = (User)user1.clone();

cUser1.setName("test2");

System.out.println(user1.toString());

System.out.println(cUser1.toString());

}

 

public static class User implements Cloneable, Serializable{

private String name;

private Map<String, String> testMap;

public User() {

testMap = new HashMap<>();

}

public User(String name) {

this();

this.setName(name);

}

public void setName(String name) {

this.name = name;

testMap.put("test", name);

}

public Object clone() {

try {

return (User)super.clone();

} catch (CloneNotSupportedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

return null;

}

}

@Override

public String toString() {

return "User [name=" + name + ", testMap=" + testMap + "]";

}

 

}

 

실행 결과 

User [name=test1, testMap={test=test2}]

User [name=test2, testMap={test=test2}]

 

결과를 보면 user1에 Map값이 잘못된걸 확인할 수 있습니다. 

레퍼런스 타입인 경우 완전 복제가 되지않습니다. 

완전히 복제하기 위해서는 해당 객체를  serialize 한 후 다시 deserialize하는 방법이 있습니다. 

직접 개발 할 수도 있지만 apache common에 잘 만들어진 Util이 있으니 그것을 이용하면 될거 같습니다. 

 

dependency 

gradle

// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3

compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'

 
maven
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>
 

변경 코드 

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
 
import org.apache.commons.lang3.SerializationUtils;
 
public class TestClone {
public static void main(String[] args) {
User user2 = new User("test1");
User cUser2 = SerializationUtils.clone(user2);
cUser2.setName("test2");
System.out.println(user2.toString());
System.out.println(cUser2.toString());
 
}

}

결과 

User [name=test1, testMap={test=test1}]

User [name=test2, testMap={test=test2}]

 

객체 복제할 때 레퍼런스 타입을 이용한다면 주의해야 할 부분입니다. 

 

자바스크립트에서 복제는 간단합니다.  아래처럼 이용하면 됩니다. 

function cloneObject(pObj){
  return JSON.parse(JSON.stringify(pObj));
}
댓글
댓글쓰기 폼