안드로이드나 자바에서 clone() 메소드 구현하기
자바(java)나 안드로이드(android), 닷넷( C#.net, VB.net, WPF ) 등의 객체지향 언어를 사용하다보면 필이 만나게 되는 문제가 바로 클론입니다.
원례는 클론을 안쓰고 하는것이 좋으나 상황적으로 클론아니면 답이 없을때가 있저 ㅡ.-;;;;
|
1. 클론이 없다면? |
대부분 무심결에 오브젝트를 생성해서 사용하지만 이렇게 생성해서 사용하는 오브젝트를 메모리에 어떻게 넣는 문제는 중요합니다.
일반적으로 new를 통해 생성자를 호출해여 오브젝트를 생성하면 자동으로 새로운공간에 새로운객체가 생성됩니다.
하지만 단순이 대입연산자(=)를 이용하면 메모리만 참조할뿐 그 객체는 새로운 녀석이 아니저.
이런 구조가 됩니다.
그림에서 보면 mC를 호출해도 objTemp1.A와 objTemp2.A 는 같은 값이 나옵니다. 같은 객체를 참조하기때문이저.
평상시에는 별문제가 되지 않지만 객체 자체를 빽업한다거나 할 일이 생기면 문제가 됩니다.
빽업한 겍체가 기존 객체랑 연결되있으니까 말이저 ㅎㅎㅎ
그럴때 쓰는 것이 클론입니다.
|
2. 클론이 있을때 |
클론메소드를 이용하면 기존 객체가 복제되어 새로운 메모리에 올라 갑니다.
mC를 호출해보면 objTemp1.A는 0이 출력되고 objTemp2.A에서는 1이 출력됩니다.
자바에서 제공하는 대부분의 오브젝트들은 클론메소드를 제공합니다. 하지만 직접만든 클래스나 오브젝트에 클론을 구현할 일을 그렇게 많지 않습니다. 객체를 보존하고 사용하는데 전역선언을 한다거나 생성자를 이용해 생성해놓고 내용을 백업한다던가 하는 방법으로 데이터를 보존할수 있는 방법이 많기 때문입니다.
그런데 다량의 데이터나 오브젝트들을 관리하는 클래스라면 클론이 편하저.(그래도 복제하는 코드 직접 구현해야 합니다. ㅜㅡ 좀 있다 자세이 이야기 하겠습니다.)
물론 성능 이슈가 있긴 하지만 말이저 ㅡ.-;
|
3. 클론을 구현하자 |
일단 클론을 구현하기 위해서는 Cloneable도구를 받아와야 합니다.
그리고 public Object clone()를 오버라이딩(재정의) 해야 합니다.
public class claCloneTest implements Cloneable { Object objA = null; String strData; public claCloneTest() { objA = new Object(); } /** * 이 객체의 복제품을 리턴한다. */ public Object clone() { //내 객체 생성 Object objReturn; try { objReturn = super.clone(); return objReturn; } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } }//end clone }//end class
이렇게 클론을 구현했습니다.
어라 그런데 써보면 이상합니다.
objA 가 재대로 복제 되지 않습니다!!
|
4. 클론은 만능이 아니다. |
이것은 객체를 복재할때 객체안에 있는 객체는 메모리주소가 복제 되기때문이저.
객체가 아닌 변수의 경우 이런현상이 없는데 이런 클론을 닷넷에서는 '가벼운 복제'라고 하더군요 ㅡ,.ㅡ;;
그림을 보면 클론은 했는데 내부에 있는 객체의 주소는 기존 객체가 가지고 있는 객체에 연결되있습니다.
그렇기때문에 이 현상을 막기위에서는 클래스 안에 있는 모든 객체도 clone()에서 클론하여 가저올 필요가 있습니다.
|
5. 클론을 완벽하게 만들자 |
이 예제에서는 Object형을 써서 그렇지만 다른 객체의 경우 클론이 지원됩니다.
이 예제에서는 Object형이 클론을 지원한다는 가정을 하고 코드를 작성합니다.
만약 클래스안에 생성한 객체가 클론을 지원하지 않는다면 그 객체에서도 따로 클론을 구현해 주어야 합니다.
/** * 이 객체의 복제품을 리턴한다. */ public Object clone() { //내 객체 생성 Object objReturn; try { objReturn = super.clone(); ((claCloneTest)objReturn).objA = this.objA.clone(); return objReturn; } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } }//end clone
이제 해보면 재대로 작동됩니다.
|
6. 안드로이드에서 가로세로 전환시 엑티비티가 초기화 되는 현상 |
7.클론을 지원하지 않는다면?
해당객체를 new로 생성한후 데이터를 하나씩 복사해야 합니다.
중간에 클론을 지원하지 않는 외부오브젝트가 있으면 복제가 불가능 할수도 있습니다.
이런경우 겉으로 보이는 데이터만 빽업이 되기 때문이죠-_-;;
닷넷에서도 마찬가지 입니다.