1

コードで説明する方が簡単なので、ここに

Object anObj;
anObj = new MyObj();
anObj = new Rectangle();
anObj.clone();//this doesnt exist because its on the root Object class

この例では、Object.clone()メソッドの代わりに何を使用できますか?

-----------------------追加情報------------------------- -----

追加情報を追加しましたが、すべての回答の途中にあるようですので、ここでも読むことができます。

こんにちは、これらはすべて、クローン作成またはコピーのトピックで本当に役立ちます。これについては、今考える必要があります。しかし、彼らは最初の質問を助けません。多分私からのより多くの情報はあなたが私が何をしたかを理解するのを助けるでしょう。

各オブジェクトのクローンをオーバーライドし、オブジェクトを完全にクローンするために必要な他のすべてのクローンおよびコピーメソッドを追加します。これには、バッファリングされたイメージをコピーするカスタムメソッドの追加が含まれます。すなわち:-

public Object clone() {//i copied from 'thelost's answer
    try { 
        CloningExample copy = (CloningExample)super.clone(); 
        copy.names = (LinkedList)names.clone(); 
        return copy; 
    } catch (CloneNotSupportedException e) { 
        return null; 
    } 
}

しかし、クラスにはObjectという変数が1つありますが、それは異なるタイプの他のさまざまなオブジェクトを保持しているため、各タイプにはcloneメソッドがありますが、各タイプかどうかを確認してからclone()を呼び出すことはできません。私のタイプは、多くのタイプがあるので非常に長くなりますが、オブジェクトを簡単にコピーまたは複製する方法がわかりません。このような静的メソッドを作成する方法はありますか?

static findTypeAndCopy(Object thisobj){ 
    if(thisobj==null) 
        return null;

    if(thisobj instanceOf MyObj1){ 
        return ((MyObj1)thisobj).clone(); 
    }else if(thisobj instanceOf MyObj2){ 
        return ((MyObj2)thisobj).clone(); 
    ... 
    etc
}

???

4

6 に答える 6

5

CloneableあなたはJavaで壊れていることに気づいたようです。

これは、 Effective Java2ndEditionの作者であるJoshBlochへのインタビューからの引用です。

clone私の本のクローン作成に関する項目を読んだ場合、特に行間を読んだ場合、私が深く壊れていると思うことがわかります。いくつかの設計上の欠陥がありますが、その最大の欠陥は、Cloneableインターフェースにメソッドがないことcloneです。そして、それは単にそれが機能しないことを意味します:何かを作ることCloneableはあなたがそれで何ができるかについて何も言いません。代わりに、それはそれが内部で何ができるかについて何かを言います。super.clone繰り返し呼び出すことによってObject'scloneメソッドを呼び出すことになった場合、このメソッドは元のフィールドコピーを返すことを示しています。

ただし、インターフェイスを実装するオブジェクトで何ができるかについては何も述べられていません。つまり、ポリモーフィック操作Cloneableを実行することはできません。clone

これが本からの引用です、アイテム11:clone慎重に上書きしてください:

[...]オブジェクトコピーの代替手段を提供するか、単に機能を提供しない方がよいでしょう。

[...]オブジェクトのコピーに対する優れたアプローチは、コピーコンストラクターまたはコピーファクトリを提供することです。コピーコンストラクターは、コンストラクターを含むクラスを型とする単一の引数をとる単純なコンストラクターです。

public Yum(Yum yum);

コピーファクトリはstatic、コピーコンストラクタのファクトリアナログです。

public static Yum newInstance(Yum yum);

関連する質問


代替案:Cloneable2.0

壊れていないような機能を本当に主張する場合はCloneable、次のように書くことができます(余分なジャズのために生成されます):

public class DupableExample {

    interface Dupable<T> {
        T dup();
    }   
    static class Sheep implements Dupable<Sheep> {
        Sheep(Sheep sheep) { }
        @Override public Sheep dup() {
            return new Sheep(this);
        }
    }
    public static void main(String[] args) {
        Dupable<?> dupable = new Sheep(null);
        System.out.println(dupable);
        System.out.println(dupable.dup());
        
        // no cast needed
        Sheep dolly2 = new Sheep(null).dup();
    }
}

出力は次のようになります(ideone.comで見られるように):

DupableExample$Sheep@{some hexadecimal code}
DupableExample$Sheep@{a different hexadecimal code, in all likelyhood}

したがって、任意Dupable<T>のを指定すると、それを呼び出しT dup()て、複製コピーであると期待するものを取得できます。

これは単なる概念実証です。実際の実装では、コピーコンストラクター/コピーファクトリ/すべてのコピーメカニズムに実際にコピーロジックが実装され、Dupable<T>トップpublicレベルになりますinterface

于 2010-08-19T12:17:37.493 に答える
4

クローンは壊れているので、クローンを避けるのが最善の方法です。
Cloneableインターフェイスにはメソッドがありませんclone。メソッドはクラスのようにclone定義されます。したがって、呼び出すには、にアクセスするオブジェクトのタイプを知る必要があります。より良いアイデアは、コピーコンストラクター(Blochが推奨するように)またはシリアル化と逆シリアル化(たとえばXMLを介して)のいずれかです。 リフレクションでアクセスできるかもしれませんが、よくわかりません。そして、私はそれを思いとどまらせます。protectedObjectcloneclone
clone

于 2010-08-19T12:08:00.837 に答える
0

clone()はObjectのメソッドであるため、クラスにクローンを作成する能力があるかどうかを確実に知ることはできません。最善の方法は、クラスがクローン可能かどうかを確認することです。通常、クラスがクローン可能である場合、それは開発者がメソッドを上書きしたことを意味しclone()ます。

しかし、それでも、Objectこのメソッドを呼び出すことはできません。

反射ソリューションがあります。しかし、ドキュメントが言うように:

cloneメソッドが反射的に呼び出されたとしても、それが成功するという保証はありません。

ここでドキュメントを読むことができ、このクラスに関するJosh Blochからの声明があります(最後の段落)。

于 2010-08-19T11:56:12.343 に答える
-1

インターフェイスが実装されているかどうかを確認し、実装されているCloneable場合はcloneメソッドを使用できます。

そして、これがあなた自身でそれを実装する方法の例です。

于 2010-08-19T11:54:57.647 に答える
-1

他の人が言っているように:Clonableは壊れているので、コピーコンストラクターなどの他のオプションを検討する必要があります。そうは言っても、本当にclone()を使用する必要がある場合に機能するソリューションは次のとおりです。

Object clone = null;
if(anObj instanceof Clonable) {
    Method cloneMethod = anObj.getClass().getMethod("clone");
    /*
     * TODO: Handle the case where an object is cloneable but 
     * does not have a public clone() method.
     */
    clone = cloneMethod.invoke(anObj);
} else {
    throw new RuntimeException("can't clone object");
}

または、Clone()を実装していない場合は、リフレクションを使用してオブジェクトをフィールドごとに複製できます...すべてのフィールドを取得し、値を新しいオブジェクトにコピーします。ただし、オブジェクトに引数なしのコンストラクターがない場合、これは注意が必要です。

于 2010-08-19T11:56:05.463 に答える
-1
interface PublicCloneable extends Cloneable{
    public Object clone();
}

class MyObject implements PublicCloneable {
    public Object clone() {
        return super.clone();
    }
}

class MainObject {
    public static void main(String[] params) {
        Object m = new MyObject();

        if (m instanceof PublicCloneable) {
            Object c = m.clone();
        }
    }
}
于 2010-08-19T12:30:43.913 に答える