2011-12-04 5 views
1

時々私は同じクラスの別のオブジェクトでオブジェクトを "置き換える"ことを望みます。 通常、これは次の方法で行います。これはJavaオブジェクトを置き換える最善の方法ですか?

コンストラクタを持つオブジェクトのクラスに:私は、オブジェクトを置換したいとき

public class Type { 

    private int field; 
    private double anotherField; 

    public Type(Type anotherTypeInstance) { 
     this.field = anotherTypeInstance.getField(); 
     this.anotherField=anotherTypeInstance.getAnotherField(); 
    } 
} 

は、だから私は単にこの

Type oldInstance = new Type(newInstance) 

は、時にはやるのは簡単で便利ながら、他の人ではありませんありません。 代替手段はありますか?

EDIT:

私は最適化アルゴリズムで "交換" のこの種を必要とします。 現在のソリューション(オブジェクト)を別のソリューションに置き換える必要があります。

+0

あなたが投稿した内容は何も「置き換える」ことはなく、(形式の)コピー/クローンを行います。 「便利ではない」ユースケースを投稿するか、達成しようとしているものに詳細を追加してください。 – Mat

+1

[Cloneableインターフェイス](http://docs.oracle.com/javase/6/docs/api/java/lang/Cloneable.html) – artistoex

+0

Question編集済み –

答えて

1

あなたは、より複雑なクラスのためのclone()を使用する場合、あなたは必ずすべて変更可能なオブジェクトことを確認する必要があり、この

@Override 
public Type clone() { 
    try { 
    return (Type) super.clone(); 
    } catch (CloneNotSupporedException cnse) { 
    throw new RuntimeException(cnse); // Never happens. 
    } 
} 

ようCloneableインターフェースとclone()メソッドを実装することができますクラスのフィールドで参照されるクラスも再帰的に複製されます。つまり、浅いコピーの代わりにディープコピーを作成します。浅いコピーの結果として発生する可能性のある偶発的な状態の共有は、デバッグが困難な問題につながります。

clone()の使用には多くの問題があります。通常、クラスの初期不変量が強制される場所であるコンストラクタを回避します。プリミティブ型以外のクラスを含むクラスでは、エラーが発生しやすくなります。また、clone()の使用は、ディープコピーを確実にするために変更が必要な場合にオブジェクトを複製した後に修正することができないため、非プリミティブ最終フィールドと互換性がありません。

例えば、このクラスを考えてみましょう:質問に投稿されたもののよう

public class Car { 
    private final Engine engine; 

    // ... 

    @Override 
    public Car clone() { 
    try { 
     Type copy = (Type) super.clone(); 
     copy.engine = (Engine) engine.clone(); // Error: final field cannot be modified. 
     return copy; 
    } catch (CloneNotSupportedException cnse) { 
     throw new RuntimeException(cnse); 
    } 
    } 
} 

コピーコンストラクタは、はるかに優れたアプローチです。

0

既存のオブジェクトのコピーを作成する標準的な方法は、Object.clone()です。

しかし、最後に覚えていないのは、clone()でした。正確に同じフィールドを持つ既存のオブジェクトのコピーが必要なのはなぜですか? 「元の」オブジェクトに影響を与えずにオブジェクトを変更したいですか?不変オブジェクトの使用を検討してください。

+0

既存のオブジェクトのコピーを作成する方法です。はい。しかし、clone()はフィールドをコピーしないことに注意してください。 clone()をオーバーライドして、自分で処理する必要があります。 – halfdan

+0

Question編集 –

+1

'Object.clone()'このメソッドは、このオブジェクトの「浅いコピー」を実行しますが、「深いコピー」操作は行いません。 – GETah

1

はい、問題ありません。より良い方法は、次のようになります。

+1

最初に 'super.clone()'を呼び出すことでクローンメソッドを実装することを強く推奨します。それ以外の場合、サブクラスが作成された場合(例えば、 'SubType')、親クラスは常に' SubType'ではなく 'Type'クラスのインスタンスを返すので、その親クラスのクローンメソッドを再利用することはできません – Robin

関連する問題