다양한 deep clone 방식별 특징들을 살펴보기 위해 Test class를 작성 했습니다.
Object 안에 Object가 있고 그 안에 Map이 있는 상황일 때 Clone 처리 후 Map의 값을 변경 시 clone된 Object에도 영향을 미치는지 테스트 해봤습니다.
결론은 아래의 2가지 방식만 영향이 없었습니다.
SerializationUtils.clone(object1);
objectMapper.readValue(objectMapper.writeValueAsString(object1), Object1.class);
이미 java bean Class가 Serializable을 implements 하고 있다면 SerializationUtils 방식도 괜찮아 보이고,
이미 java bean Class가 argument가 없는 기본 생성자를 포함 (or 다른 생성자X) 하고 있다면 objectMapper 방식이 좋을 것 같습니다.
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.springframework.beans.BeanUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
static class Object1 implements Cloneable, Serializable {
private Object2 object2;
public Object1() {}
public Object1(Object2 object2) {
setObject2(object2);
}
public Object2 getObject2() {
return object2;
}
public void setObject2(Object2 object2) {
this.object2 = object2;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
static class Object2 implements Cloneable, Serializable {
private Map<String, String> map;
public Object2() {}
public Object2(Map<String, String> map) {
setMap(map);
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public static void main(String[] args) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, String> map = new HashMap<>();
map.put("test", "t1");
Object1 object1 = new Object1(new Object2(map));
Object1 newObject1 = null;
// implements Cloneable, clone() method 필요
newObject1 = (Object1) object1.clone();
map.put("test", "t2");
System.out.println("--------------------------------------");
System.out.println("# object1.clone();");
System.out.println(objectMapper.writeValueAsString(object1));
System.out.println(objectMapper.writeValueAsString(newObject1));
// implements Serializable 필요
newObject1 = SerializationUtils.clone(object1);
map.put("test", "t3");
System.out.println("--------------------------------------");
System.out.println("# SerializationUtils.clone(object1);");
System.out.println(objectMapper.writeValueAsString(object1));
System.out.println(objectMapper.writeValueAsString(newObject1));
// spring framework 필요
BeanUtils.copyProperties(object1 , newObject1);
map.put("test", "t4");
System.out.println("--------------------------------------");
System.out.println("# BeanUtils.copyProperties(object1 , newObject1);");
System.out.println(objectMapper.writeValueAsString(object1));
System.out.println(objectMapper.writeValueAsString(newObject1));
// argument가 없는 기본 생성자 필요
newObject1 = objectMapper.readValue(objectMapper.writeValueAsString(object1), Object1.class);
map.put("test", "t5");
System.out.println("--------------------------------------");
System.out.println("# objectMapper.readValue(objectMapper.writeValueAsString(object1), Object1.class);");
System.out.println(objectMapper.writeValueAsString(object1));
System.out.println(objectMapper.writeValueAsString(newObject1));
/* 결과값
--------------------------------------
# object1.clone();
{"object2":{"map":{"test":"t2"}}}
{"object2":{"map":{"test":"t2"}}}
--------------------------------------
# SerializationUtils.clone(object1);
{"object2":{"map":{"test":"t3"}}}
{"object2":{"map":{"test":"t2"}}}
--------------------------------------
# BeanUtils.copyProperties(object1 , newObject1);
{"object2":{"map":{"test":"t4"}}}
{"object2":{"map":{"test":"t4"}}}
--------------------------------------
# objectMapper.readValue(objectMapper.writeValueAsString(object1), Object1.class);
{"object2":{"map":{"test":"t5"}}}
{"object2":{"map":{"test":"t4"}}}
*/
}
}
'Java' 카테고리의 다른 글
룬 알고리즘 체크용 java 소스 (0) | 2023.09.05 |
---|---|
null 처리에 대한 코딩 방식 (1) | 2022.07.15 |
tomcat localhost ssl 적용을 위한 키 생성 (0) | 2021.02.05 |
RSA 암호화 java 구현 class (0) | 2018.02.23 |
goo.gl api java 구현 (0) | 2016.10.06 |