개발_웹/Java

Java | clone()으로 깊은 복사하기

zuyo 2021. 5. 2. 19:50
반응형

clone()

Object 클래스의 메소드로, 이 메소드가 호출된 인스턴스의 복사본(깊은 복사)이 생성되고 복사본의 참조 값이 반환된다.

클래스가 Cloneable 인터페이스를 구현(implements)하고 있어야 clone()으로 복사가 가능하다. 그렇지 않으면 clone()을 재정의 해도 CloneNotSupportedException이 발생한다.

 

객체 복사 예시

복사할 User 클래스이다. Cloneable 인터페이스를 구현하고, clone()을 재정의한다.

User 객체 복사 시, 멤버 중의 Character란 클래스의 객체도 같이 복사해주도록 재정의한다.

 

public class User implements Cloneable {
        private String id;
        private String password;
        private Character character;
        ...
        @Override
        protected Object clone() throws CloneNotSupportedException {
                User clone = (User)super.clone();
                if (this.character != null) {
                        clone.character = (Character)this.character.clone();
                }
                return clone;
        }
        ...
}


User 객체 복사 시에 같이 복사되어야 하므로, 마찬가지로 Cloneable 인터페이스를 구현하고, clone()을 재정의한다.
User 클래스의 멤버로 들어가는 Character 클래스이다.

 

public class Character implements Cloneable {
        private String name;
        private String job;
        private int level;
        ...
        @Override
        protected Object clone() throws CloneNotSupportedException {
                // TODO Auto-generated method stub
                return super.clone();
        }
        ...
}


만약 복사하려는 객체의 클래스가 Cloneable 인터페이스를 구현하지 않았다면 CloneNotSupportedException이 발생한다.
객체를 하나 생성해서 한 번은 얕은 복사(shallow copy), 한 번은 깊은 복사(deep copy)를 해본다.

 

public class Main {
        public static void main(String[] args) {
                User user = new User("tzuyo", "12345", new Character("니케", "도적", 99));
                User shallowCopy = null;
                User deepCopy = null;
                                
                try {
                        shallowCopy = user;
                        deepCopy = (User)user.clone();
                        
                        System.out.println("user: " + user.toString());
                        System.out.println("shallowCopy: " + shallowCopy.toString());
                        System.out.println("deepCopy: " + deepCopy.toString());
                } catch (CloneNotSupportedException e) {
                        System.out.println("복사 실패");
                }
        }
}


결과 출력 화면을 보면 얕은 복사로 만든 객체는 오브젝트의 해쉬 코드 값이 원본과 같지만, clone()으로 만든 객체는 해쉬 코드 값이 다른 걸 볼 수 있다.

 

반응형