1

、、などはわかりますがdeep copy、主な疑問は、いつオブジェクト参照をディープ コピーするかということです。またはどのくらいの頻度ですか?shallow copyhow to deep copy


シナリオ 1 :
コードを検討してください。完全なコードについては、http://pastebin.com/WEgeBFNbを参照してください。

class Box{
        Position pos;
        Box(Position p){ 
           pos = p;      
        }
        Position getPosition(){
          return pos;
        }
   }

そしてmain()好き:

public class Sample{
      public static void main(String args[]){
        Position pos = new Position(3,5);
        Box box = new Box(pos);     
        pos.setX(5);
        System.out.println( box.getPosition().getX()); 
            // Will print 5, but I want Box to retain its value
      }

私は上記の要件を次の方法で達成しました。

 Box(Position p){ 
           pos = new Position(p);     // Deep cloning 
        }

Position次に、次のようなコピー コンストラクターも必要です。

Position(Position p){
     x  = p.x;
     y  = p.y;
   }

しかし、私の質問は次のとおりです。いつディープ クローニングを使用するのですか?

シナリオ 2: たとえば、ac# コードを検討します。

List<Accounts> = Mysession.getAllAccounts();. ここで、返されたオブジェクトの変更がセッション オブジェクトに反映されないようにする必要があります。(このケースは C# だけでなく、一般的にどのoop言語にもあります) したがって、ディープ クローン作成を開始すると、has-a 関係を使用して最大 5 レベルの深いオブジェクトになるため、簡単な作業ではありません。

もう一度言いますが、正確に 100% 取得するには、ディープ クローンを作成する必要があります。同意。

  1. より一般的なものは何ですか? 参照またはオブジェクトのコピーを返しますか?
  2. ディープ クローニングは面倒なプロセスであり、避けなければならないと聞きました。では、どのくらいの頻度でディープクローンを作成できますか?
  3. いくつかのシナリオ例を挙げていただけますか (コードは不要です)。
  4. 上記のbox 例のような初期化中に、クローンを使用する必要がありますpos = new Position(p)か? または通常の割り当てpos = p
4

2 に答える 2

1

オブジェクト指向プログラミングの主な目的は、オブジェクトが常に正当な状態であることを保証することでなければなりません。

したがって、オブジェクトの参照を返すときは、次のことを考慮する必要があります。

  1. 返されたオブジェクトは不変ですか?
  2. 参照を返す現在のオブジェクト (メイン オブジェクト) には、返されたオブジェクトに依存する値がありますか? (派生またはキャッシュされた値)

これらの質問に対する回答には、次の方法で対応できます。

返される参照は不変オブジェクト (String、BigDecimal など) です。

  1. アクションは必要ありません

返された参照は変更可能なオブジェクト (配列、日付など) ですが、メイン オブジェクトには派生値がありません (たとえば、装飾のみ)。

  1. アクションは必要ありません

返される参照は変更可能なオブジェクト (配列、日付など) であり、メイン オブジェクトには派生値があります。

  1. 返却する前に、オブジェクトのコピーを作成してください。これは、コピーが簡単に作成でき、メモリや時間がかからない場合に適用されます (機能以外の要件によって異なります)。

  2. 元のオブジェクトへの変更不可能な参照を返します (Collections.unmodifiable... のように)。

  3. 返されたオブジェクトへのアクセスを検出し、これらの変更についてメイン オブジェクトに通知するプロキシを返します。これにより、メイン オブジェクトは派生値を再計算でき、一貫性のない状態にならなくなります。

オブジェクト参照を取得するときは、同じ質問を自問してください。コンストラクターまたはメソッドの呼び出しを介して。

于 2013-08-02T05:20:29.903 に答える