0

不変クラスを構築したい場合は、非 final フィールドへの参照を公開しないでください。ただし、 Strings のような不変オブジェクトの場合でも?

public final class Test { // Test class is meant to be immutable

    private String s; // CAN'T MAKE THIS FINAL

    void onCreate(String s) { // a callback called ONCE after construction
        this.s = new String(s); // do I need to do this ? (protect me from me)
    }

    public String getS() {
        return new String(s); //do I need to do this ?(protect me from the world)
    }
}
4

4 に答える 4

2

理論的には、アンセーフ パブリケーションを通じて、初期化されていない ( )をTest持つクラスのインスタンスを確認することができます。これは、正しく初期化された で確認することもできます。これは を作成することで修正できます。nullsss volatile

ただし、そのようなコールバックが発生している場合は、設計を見直したいと思います。

クラスを作るとしたら、Serializableもっと多くの問題が発生するでしょう。

于 2013-12-02T04:43:12.527 に答える
1

このクラスが不変かどうかは問題ではありません (不変の定義について)。s特に、参照が別の文字列を指すように変更されても問題ありません。文字列オブジェクトは不変であるため、コピーする必要はありません。防御的コピーを使用しない場合、 の呼び出し元は、 のメソッドおよび の他の呼び出し元によってgetS使用される同じ文字列オブジェクトへの参照を取得します。それは問題ではありません。なぜなら、彼らがこの文字列に対して何しても他の指示対象に影響を与えないからです。時間と記憶の無駄になります。TestgetS

1私は反省を無視しています。このように悪意を持ってリフレクションを使用するコードは、ほとんどすべてのものを壊す可能性があり、偶然に書かれたものでも見つけにくいものでもありません。このケースについて心配することは、現実的ではありません。

于 2013-11-30T16:52:50.113 に答える