2016-09-05 7 views
1

私は暗黙のための慣習を知っていますObject#clone()super.clone()に電話をかけてコピーしたオブジェクトを取得すると言います。実際にsuper.clone()を呼び出さないObject.clone()の結果は何ですか?

しかし、もし私がそうでなければ、結果が何であるか疑問に思っています。それでは、この例を想定してみましょう:

class SomeClass implements Cloneable { 
    private Object someField; 

    public SomeClass(Object someField) { 
     this.someField = Object someField; 
    } 

    public Object clone() { 
     return new SomeClass(this.someField); 
    } 
} 

私は、これは右(TM)ではないと感じています。コピーコンストラクタやコピーメソッドが必要な場合は、それを使用するだけで、Object#clone()は使用しません。

しかし、いくつかのレガシーコードでこれにつまずいている間、私はちょうど疑問に思った:これは実際に危険ですか?またはちょうど創造的なが、実際には悪いスタイルですか?

+0

オブジェクトを深くコピーするのではなく、単純に浅くコピーします。 someFieldの超過は両方のオブジェクトに影響を与えます –

+3

super.clone()はデフォルトで浅いコピーを作成するだけなので、これは問題ではありません –

答えて

1

これは実際に危険ですか?それとも創造的ですが、実際には悪いスタイルですか?

SomeClassがサブクラス化される危険性があります。つまり、サブクラスもこのメソッドをオーバーライドする必要があります。または、同じタイプのインスタンスであることを実際に返しません。

もう1つの潜在的な問題は、オプションのフィールドがSomeClassに追加されていますが、clone()メソッドの更新を忘れることです。

super.clone()を使用する場合は、これらの問題について心配する必要はありません。

+0

super.clone()を呼び出すと、ありがとう。 – xxlali

+0

さて、問題は次のようなものです:実際にはJavaクローンAPIを使用しないことに決めましたが、あなたが行っているように見せます*。 これは最終的にこのメソッドを更新することを忘れてしまいます。コピーコンストラクタやカスタムコピーメソッドでは、おそらくそれについて考えていたでしょう。 サブクラスの引数は、実際にクローン契約を破っているためです。 –

+1

@xxlali 'super.clone()'は、メソッドを書き込んだ時点で存在していたものだけでなく、すべてのフィールドをコピーします。フィールドを追加すると、どこにコードを変更する必要はありません。 –

関連する問題