public class CloneTest {
// shallow cloning 인 경우 또는 변수할당인 경우
 @Test
 public void 변수테스트1(){
  Address add1= new Address();
        Employee emp1 = new Employee();
        add1.setHouseNo(100);

        emp1.setName("ryan");
        emp1.setAddress(add1);

      // Employee emp2 = emp1; 아래와 동일한 결과
        Employee emp2 = emp1.clone();
        emp2.setName("ryan2");

        System.out.println("emp1 : " + emp1);
        System.out.println("emp2 : " + emp2);

        System.out.println("emp1==emp2 "+(emp1==emp2));

 }
 
 class Address {

     private int houseNo;

     public int getHouseNo() {
         return houseNo;
     }

     public void setHouseNo(int houseNo) {
         this.houseNo = houseNo;
     }

     @Override
     public String toString() {
         return "houseNo : " + houseNo;
     }
     
 }

 
 class Employee implements Cloneable {
     private String name = null;
     private Address address=null;

     @Override
     public String toString() {
         return "name " + this.getName()+ " address : "+ address;
     }
     
     public Employee clone() {

         Employee emp = null;
         try {
             emp = (Employee) super.clone();
         } catch (CloneNotSupportedException e) {
             System.out.println(e);
         }
         return emp;
     }

     public Address getAddress() {
         return address;
     }

     public void setAddress(Address address) {
         this.address = address;
     }

     /**
      * @return the name
      */
     public String getName() {
         return name;
     }

     /**
      * @param name the name to set
      */
     public void setName(String name) {
         this.name = name;
     }
 }
 
 
//cloning 인 경우
 @Test
 public void 변수테스트2(){
  TestData t1 = getTestData();
  TestData t2=t1.clone();
  
  t2.getC().clear();
  t2.setA("");
  t2.getC().add("test1");
  t2.getC().add("test2");
  
  t2.c.addAll(t1.getC());
  
  System.out.println(t2.getC()+", "+t1.getA());
  
 }
 
 private TestData getTestData(){
  TestData t1 = new TestData();
  List<String> list = new ArrayList<String>();
  list.add("test3");
  list.add("test4");
  list.add("test5");
  t1.setA("1");
  t1.setA("2");
  t1.setC(list);
   
  return t1; 
 }
  
 class TestData implements Cloneable{
  private String a;
  private String b;
  private List<String> c = new ArrayList<String>();
  
  public List<String> getC() {
   return c;
  }
  public void setC(List<String> c) {
   this.c = c;
  }
  public String getA() {
   return a;
  }
  public void setA(String a) {
   this.a = a;
  }
  public String getB() {
   return b;
  }
  public void setB(String b) {
   this.b = b;
  }
  
  public TestData clone() {
   TestData data = null;
   try {
    data = (TestData) super.clone();
    List<String> clonedList = new ArrayList<String>(c.size());
       for (String t : c) {
           clonedList.add(t);
       }
    data.c = clonedList;
   } catch (CloneNotSupportedException e) {
   System.out.println(e);
   }
   return data;
  }
 }
 

}
클로닝은 shallow cloning으로 필드 멤버가 전부 primitive 타입인 경우에 유용하다. (primitive 타입이란 객체의 레퍼런스가 아닌 int, char, double 등의 단일 값을 저장하는 데이터 타입을 말한다) 하지만 변수 테스트2와 같이 멤버변수에 레퍼런스객체가 존재할 경우 단순히 clone()메소드만으로는 복사되지 않는다. TestData 클래스 처럼 clone() 메소드에 primitive 타입을 제외한 객체 타입변수는 따로 clone 작업을 해줘야 한다. 일반적으로 대부분의 컬렉션이나 배열같은 경우 clone 메소드가 구현되어 있어 그냥 사용하면 되지만 일반적인 객체나 일부 컬렉션은 clone 메소드구현이 담보되지 않아 반드시 확인후 없을 경우 따로 구현하여 사용해야 한다.

댓글

이 블로그의 인기 게시물

어쩌다 마주친 spring Error

nginx 설정정리

이클립스에서 톰캣 publish할때 에러