2011-06-17 16 views
9

私が理解したように、メソッドclone()は、Javaでオブジェクト(参照なし)をコピーする機能を提供します。しかし、私はコピーが浅いことも読んでいます。だから何のポイント?どのような能力が私に与えられるのでしょうか、簡単な訴えはありませんか?Javaのclone()メソッド

答えて

21

違いは、元のオブジェクトを変更せずにクローンオブジェクトを変更できることです。 p2上の変更はないながら

Point p = new Point(1,2); 
Point p2 = p.clone(); 
Point p3 = p; 
p2.x = 5; 
p3.y = 7; 

p3上の変更は、pにフィードバックありません。

Point p = new Point(1,2); 

      .-----. .-----. 
p -----> | x -+--> | 1 | 
      |  | '-----' 
      |  | .-----. 
      | y -+--> | 2 | 
      '-----' '-----' 


Point p2 = p.clone(); 

      .-----. .-----. .-----. 
p -----> | x -+--> | 1 | <--+- x | <----- p2 
      |  | '-----' |  | 
      |  | .-----. |  | 
      | y -+--> | 2 | <--+- y | 
      '-----' '-----' '-----' 

Point p3 = p; 

      .-----. .-----. .-----. 
p -----> | x -+--> | 1 | <--+- x | <----- p2 
      |  | '-----' |  | 
      |  | .-----. |  | 
p3 -----> | y -+--> | 2 | <--+- y | 
      '-----' '-----' '-----' 


p2.x = 5; 

      .-----. .-----. .-----. .-----. 
p -----> | x -+--> | 1 | | x -+--> | 5 | 
      |  | '-----' |  | '-----' 
      |  | .-----. |  | 
p3 -----> | y -+--> | 2 | <--+- y | <----- p2 
      '-----' '-----' '-----' 


p3.y = 7; 

      .-----. .-----. .-----. .-----. 
p -----> | x -+--> | 1 | | x -+--> | 5 | 
      |  | '-----' |  | '-----' 
      |  | .-----. |  | 
p3 -----> | y | | 2 | <--+- y | <----- p2 
      '--+--' '-----' '-----' 
       |  .-----. 
       '---> | 7 | 
        '-----' 
+0

ありがとう、しかし、私はなぜp2.xがpで何も変えない理由は分かりません。 2つの異なるオブジェクトがありますが、同じxとyを指しています(浅いコピーなので)。私は何が欠けていますか? – Tom

+0

割り当て(最後の2行で)は 'x'と' y'が指しているものを変更します。 'p.x'と' p2.x'が同じ値(同じオブジェクトを参照)を持っていても、それらは異なる変数であり、一方を代入することは他方を変えません。 (この場合はオブジェクトでもプリミティブな値ではありませんが、オブジェクトであれば同じものが有効です) –

+0

この例では、浅いクローンと深いクローンの違いは表示されません。 –

4

単純な割り当ては、オブジェクトのエイリアスを作成するだけです。 clone()では、各属性メンバもcloneオブジェクトで初期化されます。ただし、属性メンバー自体にそれ以上のオブジェクトが含まれている場合、それらはコピーされません。

7

割り当ては、インスタンスの参照を変数にコピーします。 クローン操作は、インスタンスをクローンします(クローンへの参照を割り当てます)。 割り当て

、あなたは複数オブジェクトの参照を保持複数の変数を持っていますクローニングとオブジェクトを指す複数変数になってしまいます。

SomeCloneable a = new SomeCloneable(); 
SomeCloneable b = a;      // a and b point to the same object 

/* versus */ 

SomeCloneable a = new SomeCloneable(); 
SomeCloneable b = a.clone();    // a and b point to the different objects 
+0

'Cloneable'はいえ、'クローン() 'メソッドを公開しません。 'a'と' b'を 'SomeCloneable'として宣言しなければなりません。 –

+0

@PaŭloEbermann - 良いキャッチ、ありがとう、私はそれを修正します! –

3

浅いコピーは、オブジェクトのデフォルトです:

はのは、状況が個々のステートメント(1257を仮定すると、オブジェクトになります)の後にあるか見てみましょう。クローンを無効にしてディープコピーを行うことができます。あなたがCloneableを実装して(クローンをオーバーライドする必要が深さにクローニングする

1

public class MyClass implements Cloneable { 

private Object attr = new Object(); 

@Override 
public Object clone() throws CloneNotSupportedException { 
    MyClass clone = (MyClass)super.clone(); 
    clone.attr = new Object(); 
    return clone; 
} 

@Override 
public String toString() { 
    return super.toString()+", attr=" + attr; 
} 

public static void main(String[] args) throws Exception { 
    MyClass x = new MyClass(); 
    System.out.println("X="+x); 
    MyClass y = (MyClass)x.clone(); 
    System.out.println("Y="+y); 
} 

}