3

有効な Java - 項目 2 の状態

JavaBean は、その構築の途中で矛盾した状態になることがあります。

私はこれを理解できませんでした.オブジェクトがメソッドで構築されている場合、例外が発生する必要がある場合、それはコンストラクターでも発生する可能性があります. そして、これはスレッド化とどのように関連していますか?

4

2 に答える 2

3

次の Bean が本の中で紹介されました。

NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);

これらのうち、servingSizeおよびservingsによって設定されたsetServingSize(int)およびsetServings(int)は、少なくとも本では栄養の事実の基本です.

しかし、単に電話すると:

NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setCalories(100);

その場合、servingsフィールドは設定されません。したがって、結果のインスタンスは無効な状態になります。

したがって、有効なインスタンスを期待するメソッドを呼び出すとhealthRiskCalculator.calculateHealthRisk(NutritionFacts facts)、オブジェクト内または 内で例外が発生しますhealthRiskCalculator

これで、呼び出し時に健康へのダメージを確認できますがcalculateHealthRisk()、オブジェクト インスタンスを読み取ったり使用したりするメソッドが多数ある可能性があります。さらに、他の製品に対しても多くの無効なインスタンスを作成した可能性があります。つまり、これはフェイル ファストではありません。

したがって、Bean を使用して構築されたオブジェクトを作成する確実な方法はありません。これはスレッド化に固有のものではなく、単一のスレッド内で無効な Bean インスタンスを作成できます。

于 2014-06-01T00:12:23.967 に答える
1

ThreadUtils.doFoo(FooBean fb)で動作するスレッドを生成するスレッド モデルを想像してみてくださいfbfbその計算を定義するためにそのスレッドに渡されるパラメータと同じくらい簡単です。ここで、次のコンストラクターを使用します。

public FooBean(int i, int j, int k, int l, int port){
    ThreadUtils.doFoo(this);
    someListField = Arrays.asList(i, j, k, l);
    this.port = port;
}

これによりthis、コンストラクターからのリークが発生します。リストが適切にインスタンス化されて割り当てられる前に、なんらかの誤った理由で生成されたスレッドが動作した場合、スレッドは の矛盾した状態で動作することになりますthis。たとえば、portソケットをリッスンするために新しいスレッドによって使用され、thisリークが発生した場合、ソケットはポート 0 (数値フィールドのデフォルト値) ではなくポート 0 でリッスンする可能性がありますport

実際、コンストラクターの例外thisがリークされ、他の場所から到達可能な強い参照を取得した場合、問題になる可能性があります。

ただし、次のコンストラクタは安全です。

public FooBean(int i, int j, int k, int l, int port){
    someListField = Arrays.asList(i, j, k, l);
    this.port = port;
    ThreadUtils.doFoo(this);
}

これは、Java メモリ モデルでは、スレッドが生成される前にフィールドが格納されるためです。

于 2014-04-19T12:04:49.897 に答える