5

重複の可能性:
Java でオブジェクトをコピーするにはどうすればよいですか?

Java でオブジェクトをコピーする必要があります (つまり、オブジェクトを「参照ではなく値で」コピーして、新しいオブジェクトが古いオブジェクトへの単なる参照にならないようにします)。私はクローン可能の実装にうんざりしていて、コピー コンストラクターを使用したいと考えています。ただし、コピーする必要があるクラスには、コピーする必要がある多くのメンバー変数 (100 以上) があるため、コピーするためだけに新しいコンストラクターをクラスに追加する (これはアプリケーションの 1 つの部分でのみ必要です) のは不十分な解決策のようです。その巨大な長さのために。

より良い解決策はありますか?clone() を使用する必要がありますか? コピー コンストラクターを作成できますが、すべてのフィールドを 1 つずつコピーするのではなく、リフレクティブにコピーできますか? ありがとう。

基本的には、古いオブジェクトと同じ新しいオブジェクトを作成する必要がありますが、いくつか (100 のうち約 10) のフィールドが変更されています (ただし、まだ両方のオブジェクトが必要です..そのため、新しいオブジェクトは古いもの)。私はどんな提案にもオープンです。

4

3 に答える 3

11

clone()浅いクローンを作成します - フィールドの最初のレベルのみをコピーします。clone()との使用は避けるべきですCloneable。これを正しく実装するのは非常に難しく、すぐにはわかりませんが何かが壊れる可能性が非常に高いからです。Joshua Bloch がこれについて述べていることを参照してください。

ディープ コピー、つまりオブジェクト階層全体のクローンが必要な場合は、次の 2 つのオプションを提案できます。

ただし、浅いコピーが必要な場合、つまり、すべてのフィールドを新しいオブジェクトにコピーしたいが、フィールドとフィールドのフィールド (など) が元の値を指している場合は、BeanUtils.clone(..)( commons-beanutilsから) を使用できます。 )

複製の問題は別として、100 個のメンバー変数を持つことは良い兆候ではありません。クラスを複数のクラスに分割することを検討してください (update: および外部キーを使用して複数のテーブル。もちろん、それが該当する場合。これらが本当に同じオブジェクトのプロパティである場合は問題ありません)。

于 2010-06-29T21:03:01.993 に答える
8

1 つのオプションは、シリアライゼーションを使用することです。これは最速のものではありませんが、おそらく最も安全なものの 1 つです。このサイトのコードを見てください:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectputStream;
import java.io.ObjectOutputStream;

public class DeepObjectCopy {

  public static Object clone(Object copyObject) {
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
      ObjectOutputStream oos = new ObjectOutputStream(baos);
      oos.writeObject(copyObject);
      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
      ObjectputStream ois = new ObjectputStream(bais);
      Object deepCopy = ois.readObject();
      return deepCopy;
    } catch (IOException e) {
      e.printStackTrace();
    } catch(ClassNotFoundException e) {
      e.printStackTrace();
    }
    return null;
  }
}
于 2010-06-29T21:06:42.890 に答える