Search
Duplicate

Cloneable 인터페이스와 clone 메소드

개요

Java 언어에서는 인스턴스의 복사를 실행하는 도구로 clone 메소드가 준비되어 있습니다.
clone 메소드를 실행할 경우에는 복사 대상이 되는 클래스는 java.lang.Cloneable 인터페이스를 구현할 필요가 있습니다. 복사 대상이 되는 클래스가 직접 java.lang.Cloneable 인터페이스를 구현해도 상관 없고, 하위 클래스의 어딘가에서 Clonable 인터페이스를 구현해도 상관없습니다.
Cloneable 인터페이스를 구현한 클래스의 인스턴스는 clone 메소드를 호출하면 복사됩니다. 그리고 clone 메소드의 반환값은 복사해서 만들어진 인스턴스가 됩니다.
그 내부에서 하는 일은 원래의 인스턴스와 같은 크기의 메모리를 확보한 뒤, 그 인스턴스의 필드 내용을 복사하는 것입니다.
만약 Cloneable 인터페이스를 구현하지 않는 클래스가 clone 메소드를 호출하면 예외 CloneNotSupportedException 이 발생합니다.

clone 메소드는 어디에서 정의되는 것일까?

⇒ clone 메소드는 java.lang.Object 클래스에서 정의되어 있습니다. Object 클래스는 Java의 클래스 계층의 기본 클래스이기 때문에 어느 클래스에서도 clone 메소드를 상속하게 됩니다.

Cloneable이 요구하는 메소드는?

⇒ 'Cloneable 인터페이스' 라고 하면 그 내부에 clone 메소드가 선언되어 있는 것처럼 생각하기 쉽습니다.
그러나 Cloneable 인터페이스에는 메소드가 하나도 선언되어 있지 않습니다. 이 인터페이스는 단지 'clone 에 의해 복사할 수 있다' 라는 표시로서 사용되고 있습니다.
이와 같은 표시를 하는 인터페이스를 marker interface라고 합니다.

clone 메소드는 피상적인 복사를 실행한다.

⇒ clone 메소드에 의해 이루어지는 것은 필드의 내용을 그대로 복사한다는 동작입니다.
바꾸어 말하면 필드의 앞에 있는 인스턴스의 내용까지는 고려하지 않습니다. 예를들어 필드 앞에 배열이 있었다고 할 경우, clone 메소드를 사용해서 복사를 한 경우
그 배열에 대한 참조만 복사될 뿐이고 배열의 요소 하나하나가 복사되는 것은 아닙니다.
이와 같은 필드 대 필드의 복사(field-for-field copy)를 '피상적인 복사(shallow copy)'라고 합니다. clone 메소드가 실행하는 것은 피상적인 복사입니다. clone이 수행하는 피상적인 복사 만으로 곤란한 경우에는 클래스 설계자가 clone 메소드를 오버라이드해서 자신이 필요한 '복사'를 정의할 수도 있습니다.
(clone 메소드를 오버라이드하는 경우 super.clone()을 사용한 상위 클래스의 clone 메소드의 호출을 잊지 말아야 합니다.)
clone은 복사를 할 뿐이며 생성자를 호출하는 것이 아니라는 점에 주의할 필요가 있습니다. 또한 인스턴스 생성 시 무엇인가 특수한 초기화를 필요로 하는 클래스에서는 clone 메소드 안에 처리를 기술할 필요가 있습니다.

예제코드

CloneTest.java
Main.java
실행 결과