2016-11-12 8 views
-2

アイテムのeffective javaに記載されています:は、信頼できないタイプのサブクラス化可能なパラメータの守備コピーを作成するためにクローンメソッドを使用しませんパーティー守備コピーを作成する際にクローンではなく新しいオブジェクトを作成する

これは実際には何を意味するのか理解できません。

+0

サードパーティのサブクラスがあなたのクラスである場合、 'clone()'が何をするのか分かりません。ほとんどのプロジェクトでは、これは問題になることはまずないと心配していますが、JDKではこれが心配されなければならないことです。 –

答えて

2

ここでは、このセクションで本が強調している懸念事項を示します。

public MyOtherClass implements Cloneable { 
    public Object clone() { 
     super.clone(); 
    } 
} 

public MyOtherClass { 
    private MyClass m; 

    public MyOtherClass(MyClass m) { 
     this.m = m.clone(); // Defensive copy. 
    } 
} 

public SneakyClass extends MyClass { 
    public clone() { 
     return this;   // !!!!!! 
    } 
} 

MyOtherClassコンストラクタにSneakyClassのインスタンスを渡すことによって、誰かがコンストラクタがやろうとしていることをに守備のコピーを倒すことができます。ご覧のとおり、clone()のオーバーライドでは、は対象オブジェクトのコピーを返しません。

(この場合は解決策がfinalとしてMyClassを宣言するか、finalとしてMyClass.clone()を宣言する場合。)

1

あなたが話している項目が適切に不変なクラスを実装する方法を説明しています。

の完全な段落は言う:

注意はまた、我々は守備のコピーを作成する日付のcloneメソッドを使用していないこと。 Dateは非最終型なので、cloneメソッドはクラスがjava.util.Dateであるオブジェクトを返すことは保証されません。それは悪意のある悪戯のために特別に設計された信頼できないサブクラスのインスタンスを返すことができます。そのようなサブクラスは、例えば、作成時にプライベート静的リスト内の各インスタンスへの参照を記録し、攻撃者がこのリストにアクセスできるようにすることができる。これにより、攻撃者はすべてのインスタンスを自由に治めることができます。この種の攻撃を防ぐために、は、信頼できない当事者によってサブクラス化可能なパラメータの防御的なコピーを作成するためにクローンメソッドを使用しないでください。Fooクラスはまだそれが悪意を持って変更する可能性を意味し、それが作成したインスタンスへのアクセス権を持っている

public class Foo implements Cloneable { 
    private int bar; 
    private static List<Foo> secretList = new ArrayList<>(); 

    public Foo(int bar) { this.bar = bar; } 

    @Override 
    public Foo clone() { 
     Foo copy = new Foo(this.bar); 
     secretList.add(copy); // this is the line of concern 
     return copy; 
    } 
} 

:これをしなかったclone方法を想像して、段落の残りの部分が記述されたかを示すために

たとえそれが不変クラスのメンバであってもインスタンスです。

+0

短いストーリーショート*複製されたオブジェクトは元のオブジェクトの変更に応じて常に変更されますが、これは悪い考えです* – emotionlessbananas

関連する問題