2012-05-11 6 views
13

Я анализирую следующий фрагмент кода с помощью инструмента статического анализа под названием FindBugs.сравнение строки с перечислением

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

где str - это строка, а перечисление - перечисление. Инструмент генерирует следующее предупреждение для этого кода и указывает

Этот метод вызывает equals (Object) на двух ссылках разных типов классов без общих подклассов. Согласно договору equals(), объекты разных классов всегда должны сравниваться как неравные; поэтому, согласно контракту, определенному java.lang.Object.equals (Object), результат этого сравнения всегда будет ложным во время выполнения.

если заменить выше строки кода с этим:

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

то предупреждение disappears.But Я не уверен, если предупреждение о том, что инструмент генерирует действительно так и ли я ее исправление правильный путь ? потому что я видел такие сравнения раньше и, похоже, работает правильно.

ответ

18

Ваше первое сравнение в основном неправильное. Вы сравниваете объекты совершенно разных типов (String и Enum), и они никогда не могут быть равными. даже дает мне предупреждение здесь. Он компилируется только потому, что equals() принимает Object, а не String.

Второе сравнение: .

Хотя JavaDoc is a bit harsh on name() метод, я бы на самом деле использовать его рекомендации в случае, если данный перечислимого имеет toString() перекрываться:

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

Большое спасибо за советы по использованию имени(), что делает мой текущий подход к полю id в подобных ситуациях устаревшим. – Bananeweizen

+0

Обратите внимание, что объекты разных типов, безусловно, могут быть равны в соответствии с equals(). И FindBugs, и IntelliJ ошибочны.В стандартном java-интерфейсе есть пример, где это выполняется: реализации реализации интерфейса List равны, сравнивая элементы, даже для разных подклассов List. – herman

+0

@herman: вы правы, но 'equals()' должно быть * симметрией *, что легко сделать с помощью реализаций «List» (все они основаны на 'AbstractList'), но не в случае OP. –

2

Я предложил бы использовать:

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

} 
+2

Обратите внимание, что это вызовет исключение, если 'str' не представляет никакого значения' SomeEnum' –

+0

, это было бы полезно использовать в операторах switch –

3

Я думаю, заменяющий константа для toString() может быть правильным, я бы изменил его на .name(), хотя потому, что toString нужно переоценить.

1

Насколько я знаю, вы находитесь на правильном пути.

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

Все должно быть в порядке.

3

вы можете попробовать

enum.SOMEVALUE.name() 

как это

Возвращает имя этого перечисления постоянной, так же, как заявил в своем заявлении перечислений.

Смежные вопросы