2012-05-11 18 views
13

と私はFindBugsのと呼ばれる静的解析ツールを使用して、以下のコードを分析しています。比較する文字列が列挙

if(str.equals(enum.SOMEVALUE)) {// do something}; 

ここで、strはStringであり、enumは列挙型です。ツールは、このコードと状態について次の警告を生成します。

このメソッドは、共通のサブクラスを持たない異なるクラス型の2つの参照でequals(Object)を呼び出します。 equals()の契約によれば、異なるクラスのオブジェクトは常に不等と比較されるべきです。したがって、java.lang.Object.equals(Object)で定義されているコントラクトに従って、この比較の結果は実行時に常にfalseになります。

私はこれで上記のコード行を交換する場合:

if(str.equals(enum.SOMEVALUE.toString())) {// do something}; 

、警告が、私はツールが生成する警告が本当であるかどうかわからないですdisappears.Butと私はそれを固定していますか正しい方法?私は前にそのような比較を見てきたので、正しく動作しているように見えます。

答えて

18

あなたの最初の比較は、基本的には、間違っです。完全に異なるタイプのオブジェクト(StringEnum)を比較しているため、それらは決して等しいことはありません。 は私にここでも警告を与えます。これは、equals()がではなく、Objectを受け入れるためにのみコンパイルされます。

第2の比較は、正しいあります。

方法JavaDoc is a bit harsh on name()が、私は実際にケース与えられた列挙型でそれを使用してのアドバイスはtoString()はオーバーライドしています:

if(str.equals(FooEnum.SOMEVALUE.name())) 
+0

おかげで多くのことを。 – Bananeweizen

+0

異なる型のオブジェクトは、equals()に基づいて確実に等しいことが許されています。 FindBugsとIntelliJの両方が間違っています。これが行われる標準のJava APIにも例があります.Listの実装は、Listの異なるサブクラスに対しても、要素を比較することによってequalsを実装します。 – herman

+0

@herman:あなたは正しいですが、 'equals()'は* symmetric *でなければなりません。これは 'List'実装(すべては' AbstractList'に基づいています)では簡単ですが、OPケースではできません。 –

2

を私が使用することをお勧めしたい:

if (SomeEnum.SOMEVALUE == SomeEnum.valueOf(str)) { 

} 
+2

'str'が' SomeEnum'値を表さない場合、これは例外をスローすることに注意してください。 –

+0

これはswitch文での使用に役立ちます –

3

私はtoString()のために、一定の交換だと思いますtoStringをオーバーライドする必要があるので、私は.name()のためにそれを変更します。

1

は、私の知る限りでは、あなたは正しい道です。

if(str.equals(enum.SOMEVALUE.toString())) {// do something}; 

これは問題ありません。

3

あなたはそれ

として

enum.SOMEVALUE.name() 

を試すことができますが、その列挙型宣言で宣言まったく同じように、この列挙型定数の名前を返します。廃止された似たような状況でidフィールドの私の現在のアプローチを作り、名前を()を使用してのアドバイスを