2009-09-06 29 views
32

Javaで可変ブール値フィールドが必要です(このフィールドはget *メソッドで後で返しますが、このフィールドを変更する必要があります)。Javaの変更可能なブール値フィールド

Booleanクラスにset *メソッドがないため、ブール値が機能しません(ブール値は不変ですが、参照のみを変更できますが、オブジェクト自体は変更できません)。

私はサイズ1のブール配列を使用することができますね。しかし、おそらくより洗練されたソリューションがありますか?

なぜJavaにこのような単純なことがないのですか?

+5

ブール値が通常使用してテストされ

/* Boolean to be passed as reference parameter */ public class Bool { private boolean value; public Bool() { this.value = false; } public boolean is() { return this.value; } public void setTrue() { this.value = true; } public void setFalse() { this.value = false; } } 
'isXXX'方法を'getXXX'の代わりに – pjp

+1

@pjp' isXXX'はプリミティブ 'boolean'のためだけです。それらの 'Boolean'のために' getXXX'に固執すべきです。 –

答えて

53

変更できないクラスは、使いやすくなっています。それらは決して変更されず、並行コードには問題はありません。 (基本的に、それらを壊す可能性は少なくなります)

ブール値への参照を返す場合は、複数のスレッドを扱っているか普通のorg.apache.commons.lang.mutable.MutableBooleanの場合はjava.util.concurrent.atomic.AtomicBooleanを使用できます。

+2

私はjava.lang.Stringコメントオブジェクトに "mutable"と書きましたが、再度変更することはできませんでした。 :-) –

+1

これは織りなすものです。おそらく私は本当にAtomicBooleanを使用する必要があります...ありがとう – javapowered

+0

hm ..これは私がjavadocで読んだことです: "AtomicBooleanは、原子的に更新されたフラグなどのアプリケーションで使用され、ブール代数の代わりとして使用することはできません。どうして? – javapowered

4

ブールプリミティブを使用しないのはなぜですか?

private boolean myFlag = false; 

public void setMyFlag(boolean flag) { 
    myFlag = flag; 
} 

必要であれば、あなたのgetterメソッドが原因autoboxingの魔法に、ブールを返すことができます。これにより、プリミティブとそのオブジェクトに相当するもの(例えばブール値とブール値、またはintと整数)との間の互換性を容易にすることができます。

あなたの編集した返信を解決するには利用可能なメソッドは、

public Object getAttribute(String attributeName) 

です。オートボクシングされたブール値を返すことで実装できます。

+0

私は何かを設定する特別なメソッドを追加したくない...すべてはgetAttributeから返されたObjectを介して実装する必要があります。これは私が非常にトップクラスのクラスのインターフェイスを変更したくないためです。 私が必要とするのは可変ブールオブジェクトです... java.util.concurrent.atomic.AtomicBooleanはおそらく正しい選択です – javapowered

+0

あなたが何をやっているのか理解していますが、わかりませんこれは良いデザインです。私は、オブジェクトを変更するためにサードパーティのコードに渡すのではなく、フィールドを操作した後に見えるようにすることを期待しています。つまり、フィールドを見て一貫した状態を維持するのは、オブジェクトを含むオブジェクトの責任です。ただ、頭が上がっています(私が気付いていない制約の下で作業している可能性があります)。 –

+0

私はほとんどの場合、そのような実践。 でも「findbugs」は、オブジェクトが第三者によって変更される可能性があるため、「配列の戻り値の型」を「設計不良」と報告します。 これはすでに書かれているコードの多くですが、これ以上のものを追加する必要はありません:) また、私のフィールドの名前から、サードパーティによって変更されるはずであることは明らかです。大きな問題ではありません:) – javapowered

4

ブールプリミティブを使用するのはどうですか?

private boolean value; 

public void setValue(boolean value) { 
    this.value = value; 
} 

public boolean getValue() { 
    return value; 
} 
+0

これは動作しますが、フィールドごとに2つのメソッドを記述する必要があります。 私は既存のインターフェイスを変更したくありません。私が持っている唯一の方法は次のとおりです。 public Object getAttrbiute(String attributeName) – javapowered

+2

物事を設定する機能を追加することは、常識的に言えば、インタフェースを変更することです。したがって、変更を表現して追跡するために、実際に書き込まれたインタフェースを変更するのが最善です。 – soru

+0

@soru +1それは問題を考える良い方法です。 – dhable

26

たぶん

class BooleanHolder { 
    public boolean value; 
} 

または(あなたの代わりに、プリミティブbooleanのクラスBooleanを使用する必要があります意味)ジェネリックホルダークラスを作る自分でラッパークラスを記述します。

class Holder<T> { 
    public T value; 
} 

あなたは値自体の代わりにラッパー・クラスを戻します。これにより、ラッパー内の値を変更することができます。

+4

これは動作しますが、サイズ1の配列は少し単純です。img :) – javapowered

+0

1より大きい値が必要な場合は、BooleanHoldersの配列を作成します。 – nos

+0

ブール値として使用することはできません。 –

-1

実際には、呼び出し元が返される内容を操作してオブジェクトのブール値を変更できるようにしたいと言っていますか?オブジェクトと呼び出し元が参照を共有するようにするには?

 
class OddClass { 
    private Boolean strangeFlag; 
    public Object getAttrbiute(String attributeName) { 
     if (attributeName.equals("strangeflag")) return (Object)strangeFlag; 
     ... 
    } 
} 

そして、発信者が行います:その後、

 
    Boolean manipulableFlag = (Boolean) myOddClass.getAttrbiute ("strangeflag"); 

そして後で、呼び出し側がmanipulableFlagの値を変更した場合、あなたはその変更がで発生したい

ちょうどので、私は与えられた、理解しますcallerが代わりにsetAttrbiuteメソッドを使用したかのように、OddClassインスタンス。

あなたが求めていることはありますか?

この場合、Adamの示唆するようにホルダークラスが必要です。

+0

そうです、あなたは正しいことを理解しています。ホルダークラスは重大な回避策です。少なくとも1要素の配列を使用できますが、たぶんjava.util.concurrent.atomic.AtomicBooleanが最適です。 – javapowered

19

あなたはあなたがアンドロイドを使用している場合、あなたはどのandroid.util.Mutable *オブジェクトを使用することができますブール配列

final boolean[] values = { false }; 
values[0] = true; 
+6

@monzonj: 'java.util.concurrent'クラスは' synchronized'を使用しません。オプティマイズされたロック構成。 'AtomicBoolean'は、' boolean'のための包含として使用されると、パフォーマンス上のオーバーヘッドは全くありません。それ以外の方法を示すことができれば、私たちに提示してください。 – skaffman

+5

@monzonj:どんな場合でも、パフォーマンス上のオーバーヘッドはほとんどありません。また、正しい仕事に適切なツールを使用することで多くのことが得られます。あなたが測定できないマイクロ・パフォーマンスのヒットについて何を考えているかに関わらず、この高度に最適化されたクラスが理由で作成されました。 –

+2

@monzonj - アトミックなアサーションは "同期によってのみ行うことができます" *は誤って通知されています。ロックフリーの同期の概念があります。もしあなたが実際にAtomicBooleanのソースを見るなら、どこにでも 'synchronized'キーワードを使用していないことを見てください!あなたはあなたの知らない言葉で間違った情報を広げています。 –

3

を使用し、その後のJava 5以降を使用している場合さまざまなプリミティブ値をラップします。例えば、SDKのソースからの引用:

public final class MutableBoolean { 
    public boolean value; 

    public MutableBoolean(boolean value) { 
     this.value = value; 
    } 
} 
1

私はほとんどが独自のラッパークラスを書くためにアダムからだっ気に入っ答え... OK

関連する問題