1

宣言ではなくコンストラクターで定義されている場合、静的プロパティを final にすることはできますか?

不変のインスタンスを作成するカスタム クラスを作成する方法を知っています。しかし、標準クラスの不変オブジェクトを作成することは可能ですか? たとえば、オブジェクト、JPanel、Calendar などでしょうか。

4

3 に答える 3

3

しかし、標準クラスの不変オブジェクトを作成することは可能ですか?

いいえ、Java にはこれをサポートするものは何もありません。あなたができることは、参照がどれだけ広く公開されているかを制限し、それにアクセスできるコードがそれを変更しないようにすることだけです. もちろん、読み取り専用操作のみを公開する独自のラッパータイプを作成し、それを自由に公開することもできます。

編集: コメントに記載されているように、JDK 内でコレクション用にこれに対するサポートがいくつかあります。Guavaは、より完全に不変のコレクションとそれらのビルダーを提供します。ただし、可変型のオブジェクトを取得して、その不変ビューを返すという汎用的な目的はありません。

于 2012-05-01T15:54:21.000 に答える
2

静的初期化

宣言ではなくコンストラクターで定義されている場合、静的プロパティを final にすることはできますか?

static final属性が宣言されている場合、またはstatic { }ブロック内にある場合にのみ、属性を割り当てることができます。コンストラクターが呼び出されるまでには手遅れですがnull、すべてのstaticコードが最初に評価されるため、参照は既に割り当てられています。

のようにprivate static final String s = "Hello World!";

また

private static final String s;
static { s = "Hello World!"; }

動的プロキシ

不変のインスタンスを作成するカスタム クラスを作成する方法を知っています。しかし、標準クラスの不変オブジェクトを作成することは可能ですか? たとえば、オブジェクト、JPanel、Calendar などでしょうか。

動的プロキシを使用して、実際に行うことの代わりにスローするなど、setXXX()UnsupportedOperationExceptionすべての変更メソッドを使用できます。私はこのアプローチは半ハックだと思いますが、彼らはこれを Java に組み込み、まさにこのような状況に備えているため、この種の問題のためだけに設計されました。

関連するインターフェースと命名規則によっては、ラッパーを自分で手動で作成するのと同じくらい多くの作業が必要になる場合があります。

したがって、Javaでは間違いなく可能です。クラスを不変にする開始点であるa のメソッドを無効にする例を次に示します。.add()List

金属を打つ

CGLibでも同じことができますが、実際に使いやすいドキュメントや例がないため、完全を期すためにここで言及するだけにとどめます。finalまた、これがクラスの動作を変更する唯一の方法です。JMock は、finalクラスの Mock 実装を提供するためにこれを行います。. これは深い魔法ですが、本当にこれを行う必要がある場合は可能です。

于 2012-05-01T16:03:33.513 に答える
1

質問の最初の部分について、私が正しく読んでいれば:

class Test{

    public static final int x;
    public final int y;

    public Test(){
        y = 16;
    }    

    static{
        x = 42;
    }

}

基本的に、static finalフィールドは静的初期化ブロックで初期化することもでき、finalフィールドはコンストラクターで初期化することもできます。

于 2012-05-01T15:59:58.990 に答える