복제 가능 Java 정보
Java Cloneable
에 대해 설명하는 자습서를 찾고 있었지만 좋은 링크를 얻지 못했으며 어쨌든 Stack Overflow가 더 분명한 선택이되고 있습니다.
다음을 알고 싶습니다.
Cloneable
Cloneable
인터페이스 를 구현하여 객체의 복제본 또는 사본을 가질 수 있음을 의미합니다 . 그렇게하는 것의 장점과 단점은 무엇입니까?- 오브젝트가 복합 오브젝트 인 경우 재귀 복제는 어떻게 발생합니까?
가장 먼저 알아야 할 것은 Cloneable
-사용하지 마십시오.
Cloneable
올바른 복제를 구현하는 것은 매우 어렵고 노력할 가치가 없습니다.
대신 apache-commons SerializationUtils
(deep-clone) 또는 BeanUtils
(shallow-clone) 과 같은 다른 옵션을 사용 하거나 단순히 복사 생성자를 사용하십시오.
Cloneable
접근 방식의 많은 단점을 설명 하는를 사용한 복제에 대한 Josh Bloch의 견해를 보려면 여기 를 참조하십시오 . ( Joshua Bloch 는 Sun 직원이었으며 수많은 Java 기능 개발을 이끌었습니다.)
Cloneable 자체는 불행히도 마커 인터페이스 일뿐입니다. 즉, clone () 메서드를 정의하지 않습니다.
하는 일은 보호 된 Object.clone () 메서드의 동작을 변경하는 것입니다.이 메서드는 Cloneable을 구현하지 않는 클래스에 대해 CloneNotSupportedException을 발생시키고이를 수행하는 클래스에 대해 멤버 단위 얕은 복사를 수행합니다.
이것이 당신이 찾고있는 행동이라 할지라도, 당신은 그것을 공개하기 위해 자신 만의 clone () 메소드를 구현해야 할 것입니다.
자신 만의 clone ()을 구현할 때 아이디어는 super.clone ()에 의해 생성 된 객체로 시작하여 올바른 클래스임을 보장 한 다음 얕은 사본이 아닌 경우 추가 필드 채우기를 수행하는 것입니다. 당신이 원합니다. clone ()에서 생성자를 호출하면 하위 클래스가 자신의 추가 복제 가능한 논리를 추가하려는 경우 상속이 중단되므로 문제가 될 수 있습니다. super.clone ()을 호출하면이 경우 잘못된 클래스의 객체를 얻게됩니다.
이 접근 방식은 생성자에서 정의 될 수있는 모든 논리를 우회하므로 잠재적으로 문제가 될 수 있습니다.
또 다른 문제는 clone ()을 재정의하는 것을 잊은 모든 서브 클래스가 기본 얕은 복사본을 자동으로 상속한다는 것입니다. 이는 변경 가능한 상태 (이제 소스와 복사본간에 공유 됨)의 경우 원하는 것이 아닐 가능성이 높습니다.
대부분의 개발자는 이러한 이유로 Cloneable을 사용하지 않고 대신 복사 생성자를 구현합니다.
Cloneable에 대한 자세한 정보와 잠재적 인 함정에 대해서는 Joshua Bloch의 Effective Java 책을 적극 권장합니다.
- 복제는 생성자없이 객체를 구성하는 언어 이외의 방법을 호출합니다.
- 복제는 어떻게 든 CloneNotSupportedException으로 처리하거나 처리하기 위해 클라이언트 코드를 귀찮게해야합니다.
- 이점은 적습니다. 복사 생성자를 수동으로 작성할 필요가 없습니다.
따라서 Cloneable을 신중하게 사용하십시오. 모든 일을 올바르게하기 위해 신청해야하는 노력에 비해 충분한 혜택을주지는 않습니다.
복제는 기본 프로그래밍 패러다임입니다. Java가 여러 가지 방법으로 제대로 구현되지 않았을 수 있다는 사실이 복제 필요성을 전혀 줄이지 않습니다. 또한 원하는대로 얕고 깊고 혼합 된 방식으로 작동하는 복제를 쉽게 구현할 수 있습니다. 원하는 경우 Cloneable을 구현하지 않고 함수에 복제 이름을 사용할 수도 있습니다.
A, B 및 C 클래스가 있다고 가정합니다. 여기서 B와 C는 A에서 파생됩니다. 다음과 같은 A 유형의 개체 목록이있는 경우 :
ArrayList<A> list1;
이제이 목록에는 A, B 또는 C 유형의 개체가 포함될 수 있습니다. 개체가 어떤 유형인지 알 수 없습니다. 따라서 다음과 같이 목록을 복사 할 수 없습니다.
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
list2.add(new A(a));
}
개체가 실제로 B 또는 C 유형이면 올바른 복사본을 얻을 수 없습니다. 그리고 A가 추상적이라면 어떨까요? 이제 어떤 사람들은 이것을 제안했습니다.
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
if(a instanceof A) {
list2.add(new A(a));
} else if(a instanceof B) {
list2.add(new B(a));
} else if(a instanceof C) {
list2.add(new C(a));
}
}
이것은 아주 아주 나쁜 생각입니다. 새로운 파생 유형을 추가하면 어떻게됩니까? B 또는 C가 다른 패키지에 있고이 클래스에 액세스 할 수없는 경우 어떻게합니까?
당신이하고 싶은 것은 이것입니다 :
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
list2.add(a.clone());
}
많은 사람들이 복제의 기본 Java 구현이 문제가되는 이유를 지적했습니다. 그러나 다음과 같이 쉽게 극복 할 수 있습니다.
클래스 A :
public A clone() {
return new A(this);
}
클래스 B :
@Override
public B clone() {
return new B(this);
}
클래스 C :
@Override
public C clone() {
return new C(this):
}
동일한 함수 이름을 사용하여 Cloneable을 구현하지 않습니다. 마음에 들지 않으면 다른 이름을 지정하십시오.
A) 복사 생성자에 비해 복제의 장점은 많지 않습니다. 아마도 가장 큰 것은 똑같은 동적 유형의 새 객체를 만드는 기능 일 것입니다 (선언 된 유형이 복제 가능하고 공개 복제 메서드가 있다고 가정).
B) The default clone creates a shallow copy, and it will remain a shallow copy unless your clone implementation changes that. This can be difficult, especially if your class has final fields
Bozho is right, clone can be difficult to get right. A copy constructor/factory will serve most needs.
What are disadvantages of Cloneable?
Cloning is very dangerous if the object whom you are copying has composition.You need to think about below possible side effect in this case because clone creates shallow copy:
Let say you have one object to handle db related manipulation. Say, that object has Connection
object as one of the property.
So when someone creates clone of originalObject
, The object being created, let say, cloneObject
. Here the originalObject
and cloneObject
hold the same reference for Connection
object.
Let say originalObject
closes the Connection
object, so now the cloneObject
will not work because the connection
object was shared between them and it was actaually closed by the originalObject
.
Similar problem may occur if let say you want to clone a object which has IOStream as a property.
How does the recursive cloning happen if the object is a composite object?
Cloneable performs shallow copy. Meaning is that data of original object and clone object will point to the same reference/memory. contrary in the case of deep copy, data from memory of original object is copied to the memory of clone object.
참고URL : https://stackoverflow.com/questions/4081858/about-java-cloneable
'IT story' 카테고리의 다른 글
미니 버퍼에 현재 파일의 전체 경로를 표시하는 기능 (0) | 2020.09.02 |
---|---|
SQL Server에서는 언제 GO를 사용해야하며 언제 세미콜론을 사용해야합니까? (0) | 2020.09.02 |
jsonpath로 회원 수? (0) | 2020.09.02 |
Python에서 목록의 첫 번째 위치에 삽입 (0) | 2020.09.02 |
왜이 구조체 크기가 2가 아닌 3입니까? (0) | 2020.09.02 |