클론 방식을 올바르게 재정의하려면 어떻게 해야 합니다.
슈퍼클래스가 없는 오브젝트 중 하나에 딥클론을 구현해야 합니다.
체크박스를 켜면 이 좋을까요?CloneNotSupportedException슈퍼클래스에 의해 던져진 (즉,Object
동료는 다음과 같이 처리하라고 조언했습니다.
@Override
public MyObject clone()
{
MyObject foo;
try
{
foo = (MyObject) super.clone();
}
catch (CloneNotSupportedException e)
{
throw new Error();
}
// Deep clone member fields here
return foo;
}
좋은 솔루션이라고 생각합니다만, StackOverflow 커뮤니티에 전달하고, 그 외의 통찰력이 있는지 확인해 보고 싶다고 생각하고 있습니다.감사합니다!
꼭 이 제품을 사용해야만 합니까?clone대부분의 사람들은 자바가clone장났습습니니다
Josh Bloch on Design - Copy Constructor vs Cloning
에 관한 , 제에 복제는 없다, 복제는 없다, 라고 입니다.
clone[...] [...] [...] [...] [...] [...] [...] ...]워...]워 is is is is is is is is is is is is is is ]Cloneable고났지 、 어어날어야야
이 주제에 대한 자세한 내용은 그의 책 "Effective Java 2nd Edition, Item 11: Override thisdlyly"에서 읽을 수 있습니다.대신 복사 생성자 또는 복사 팩토리를 사용할 것을 권장합니다.
할 것 실천을 하는지 했습니다.clone을 사용법
이모복 잡잡 ?말? ????드 a. if iflementslementslementslementslementslementslementslements that that를 구현하는 클래스를 확장하면
Cloneable때문에 잘 짜여진 것을 하는 것 외에는 선택의 여지가 거의 없습니다.고객은유한솔루션의실장을실행할수있습니다.clone방법.그렇지 않으면 오브젝트 복사 대체 수단을 제공하거나 단순히 기능을 제공하지 않는 것이 좋습니다.
강조점은 내 것이 아니라 그의 것이었다.
수 했기 clone때 할 수 은 다음과 이 경우 꼭 합니다.MyObject extends java.lang.Object implements java.lang.Cloneable만약 그렇다면, 당신은 절대 잡히지 않을 것이라고 장담할 수 있다.CloneNotSupportedExceptionAssertionError일부에서 제시된 바와 같이 타당하다고 생각되지만 이 경우 캐치블록이 입력되지 않는 이유를 설명하는 주석을 추가할 수도 있습니다.
다른 했듯이, 해 볼 수 것입니다.clone하지 않고super.clone.
복사 생성자를 구현하는 것이 더 간단할 수 있습니다.
public MyObject (MyObject toClone) {
}
하면 를 덜 수 .CloneNotSupportedException , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,final필드 및 반환 유형을 걱정할 필요가 없습니다.
코드 작성 방법은 "표준" 방식에 상당히 가깝습니다.난 던질 거야AssertionError어획량 내에서요.그것은 그 회선에 절대 도달해서는 안 된다는 것을 나타냅니다.
catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
하다, , 하다, 하다, 하다, 하다, 이렇게 두 가지 경우가 있습니다.CloneNotSupportedException척됩니니다다
- 중인 .
Cloneable는 최종적으로 (복제가)로 되는 것을 합니다).Object의론클메메클 。 가 실장되어 있는Cloneable(서브태클이 적절하게 상속되기 때문에) 이 일은 일어나지 않습니다. - 가 '클론 '일 때의 클로너빌리티를 입니다.이는 슈퍼클래스가 클론화되지 않도록 하기 위해 권장되는 방법입니다.
Cloneable.
할 수 는 슈퍼클래스에).try의 콜링 「Calling」에서 .super.clone()) 및하게 실장해야 하지 마십시오.이것은, 「」, 「」, 「」, 「」, 「」, 「」, 「」를 실장할 .Cloneable.
기본적으로 오류는 반드시 기록해야 하지만 이 경우 클래스의 정의를 잘못했을 경우에만 발생합니다.해 주세요.NullPointerException(또는 이와 유사) - 코드가 기능하고 있는 경우에는 느려지지 않습니다.
다른 상황에서는 이 상황에 대비할 필요가 있습니다.특정 오브젝트가 복제 가능하다는 보장은 없습니다.따라서 예외를 검출할 때는 이 조건에 따라 적절한 액션을 취해야 합니다(기존 오브젝트를 계속하여 serialize-deserialize, serialize 등 대체 클로닝 전략을 실행).IllegalParameterException(복제 가능 등에 의한 파라미터가 필요한 경우)
편집: 전반적으로 그렇다는 점을 지적해야 합니다만,clone()를 올바르게 실장하는 것은 매우 어려운 일이며, 발신자가 반환값이 자신이 원하는 값인지 아닌지를 파악하는 것은 매우 어려운 일입니다.심층 클론인지 얕은 클론인지를 검토할 때는 이 값을 2배로 알 수 있습니다.모든 것을 피하고 다른 메커니즘을 사용하는 것이 종종 더 낫다.
시리얼라이제이션(serialization이것이 가장 빠른 해결책은 아니지만 종류에 따라 다르지는 않습니다.
다음과 같이 보호된 복사 생성자를 구현할 수 있습니다.
/* This is a protected copy constructor for exclusive use by .clone() */
protected MyObject(MyObject that) {
this.myFirstMember = that.getMyFirstMember(); //To clone primitive data
this.mySecondMember = that.getMySecondMember().clone(); //To clone complex objects
// etc
}
public MyObject clone() {
return new MyObject(this);
}
대부분의 답변이 유효한 만큼, 당신의 솔루션은 실제 Java API 개발자가 그것을 하는 방식이기도 합니다.(Josh Bloch 또는 Neal Gafter 중 하나)
다음은 openJDK ArrayList 클래스의 발췌입니다.
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
여러분들이 눈치채고 다른 분들이 언급했듯이CloneNotSupportedException를 실장한다고 선언했을 경우, 에서는, 튕겨질 가능성은 거의 없습니다.Cloneable인터페이스입니다.
또한 오버라이드된 메서드에서 새로운 작업을 수행하지 않으면 메서드를 오버라이드할 필요가 없습니다.개체에 대해 추가 작업을 수행해야 하거나 개체를 공개해야 하는 경우에만 재정의하면 됩니다.
궁극적으로, 여전히 그것을 피하고 다른 방법으로 하는 것이 최선이다.
public class MyObject implements Cloneable, Serializable{
@Override
@SuppressWarnings(value = "unchecked")
protected MyObject clone(){
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
ByteArrayOutputStream bOs = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bOs);
oos.writeObject(this);
ois = new ObjectInputStream(new ByteArrayInputStream(bOs.toByteArray()));
return (MyObject)ois.readObject();
} catch (Exception e) {
//Some seriouse error :< //
return null;
}finally {
if (oos != null)
try {
oos.close();
} catch (IOException e) {
}
if (ois != null)
try {
ois.close();
} catch (IOException e) {
}
}
}
}
java의 Cloneable 구현이 실패했다고 해서 자체 복제를 할 수 없는 것은 아닙니다.
OP의 진짜 목적이 딥 클론 작성이었다면 다음과 같은 인터페이스를 작성할 수 있다고 생각합니다.
public interface Cloneable<T> {
public T getClone();
}
그런 다음 앞에서 언급한 프로토타입 컨스트럭터를 사용하여 구현합니다.
public class AClass implements Cloneable<AClass> {
private int value;
public AClass(int value) {
this.vaue = value;
}
protected AClass(AClass p) {
this(p.getValue());
}
public int getValue() {
return value;
}
public AClass getClone() {
return new AClass(this);
}
}
및 AClass 오브젝트필드를 가진 다른 클래스:
public class BClass implements Cloneable<BClass> {
private int value;
private AClass a;
public BClass(int value, AClass a) {
this.value = value;
this.a = a;
}
protected BClass(BClass p) {
this(p.getValue(), p.getA().getClone());
}
public int getValue() {
return value;
}
public AClass getA() {
return a;
}
public BClass getClone() {
return new BClass(this);
}
}
이렇게 하면 @Suppress Warnings나 기타 교묘한 코드 없이도 클래스 BClass 개체를 쉽게 심층 복제할 수 있습니다.
언급URL : https://stackoverflow.com/questions/2326758/how-to-properly-override-clone-method
'programing' 카테고리의 다른 글
| URL 및 파일 이름을 안전하게 하기 위해 문자열을 삭제하시겠습니까? (0) | 2022.12.24 |
|---|---|
| Python에서의 Bash 명령어 실행 (0) | 2022.12.24 |
| str==의 차이점은 무엇입니까?C의 특수 및 str[0]=='\0'은 무엇입니까? (0) | 2022.12.24 |
| 엔티티 프레임워크가 "같은 키를 가진 항목이 이미 추가되었습니다"를 슬로우합니다. (0) | 2022.12.24 |
| MySQL SELECT가 최근 며칠 동안입니까? (0) | 2022.12.13 |