2011년 2월 10일 목요일

clone( ) 방식 - 깊은 복사/ 얕은 복사- deep copy shallow copy

사실 예전의 자바가 속도가 좋지 않았다는 사실은 누구나 공감하는 사실이다. Hotspot VM 이 나온 이유역시 이러한 데에서 비롯되었고..

자바가 느린 이유중에 하나는 역시 객체 생성이다. 메모리에 새로운 공간을 할당하고 거기에 데이터를 넣는 방식의 처리는 OOP에서는 피해갈 수 없지만 또한 이때문에 발생하는 성능의 저하는 어쩔 수 없다.

결국 OOP는 속도를 개선하기 위해서 다양한 방법을 시도했는데.. 대표적인 것들이 바로 pooling, caching기법, clone기법이라고 할 수 있다.

Cloneable 인터페이스를 이용하면 우리는 객체를 손쉽게 복사할 수 있다. 객체 생성을 해서 넣는 과정을 생략하고도 원본에 대한 또 다른 객체를 만들 수 있다. clone의 스펙을 보면 equals()가 반드시 true여야 한다는 보장은 하지 않아도 되기 때문에 복사본 객체가 아니라 데이터의 카피로도 사용할 수 있다는 얘기이다.

Shallow Copy

간단히 말하면 객체를 복사하는데 그 안의 내용물 마저 복사하지는 않는다는 얘기이다.

public class Origin implements Cloneable
{

 private String id;

 private String pw;

 private SubOrigin sub;

 ...

위와 같은 객체를 복사한다고 가정하자.

  Origin origin = new Origin();


  Origin cloneObj = (Origin) origin.clone();


위의 객체를 System.out.println()으로 보면 두 객체는 다른 주소값을 사용한다. 하지만 문제는 SubOrigin 에 있다.

ShallowCopy는 특정 객체를 복사할 때 피상적인 복사만 하게 된다.

ShallowCopy는 복사본 객체안에 있는 sub의 주소값이 원복 객체의 sub의 주소값과 동일하게 나온다.

이렇게 표면만 복사하는 것을 Shallow Copy라 하고, sub와 같은 하위 객체마저도 복사하는 방식을 deep copy라고 한다.


 protected Object clone(){
  try {
   //shallow copy
   //return super.clone();
   Origin cloneObj = (Origin)super.clone();
   cloneObj.setSub((SubOrigin)this.sub.clone());
  
   return cloneObj;
  
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
  return null;
 }


위에 있는 소스를 보면 현재 객체의 복사본을 만든후에 하위 객체의 복사본을 만들어 주입하는 방식으로 작성한다.

댓글 없음:

댓글 쓰기