Переключатель без перерыва - PullRequest
23 голосов
/ 19 декабря 2011

У меня есть оператор switch, как показано ниже. Обратите внимание, что нет перерыва. Findbugs сообщает об ошибке только для второго оператора case. Ошибка: Оператор Switch найден, когда один случай переходит к следующему.

switch(x) {

    case 0:
        // code

    case 1:
        // code

    case 2:
        // code
}

Ответы [ 6 ]

72 голосов
/ 19 декабря 2011

Findbugs показывает, что переход от одного case к следующему, как правило, не очень хорошая идея, если в первом есть какой-либо код (хотя иногда его можно использовать для хорошего эффекта). Поэтому, когда он видит второе case, а не break, он сообщает об ошибке.

Так, например:

switch (foo) {
    case 0:
        doSomething();
    case 1:
        doSomethingElse();
    default:
        doSomeOtherThing();
}

Это совершенно правильный Java, но, вероятно, он не выполняет то, что задумал автор: если foo равно 0, всех трех функций doSomething, doSomethingElse и doSomeOtherThing запустить (в таком порядке). Если foo равно 1, только doSomethingElse и doSomeOtherThing работают. Если foo - любое другое значение, запускается только doSomeOtherThing.

Для сравнения:

switch (foo) {
    case 0:
        doSomething();
        break;
    case 1:
        doSomethingElse();
        break;
    default:
        doSomeOtherThing();
        break;
}

Здесь будет работать только одна из функций, в зависимости от значения foo.

Так как забыть о break - это распространенная ошибка кодирования, такие инструменты, как Findbugs, отмечают ее для вас.

Существует распространенный вариант использования, когда у вас есть несколько case операторов подряд с no промежуточным кодом:

switch (foo) {
    case 0:
    case 1:
        doSomething();
        break;
    case 2:
        doSomethingElse();
        break;
    default:
        doSomeOtherThing();
        break;
}

Там мы хотим позвонить doSomething, если foo это 0 или 1. Большинство инструментов не помечают это как возможную ошибку кодирования, потому что в case 0 до case 1 нет кода, и это довольно распространенный шаблон.

4 голосов
/ 19 декабря 2011

Я написал их как комментарии, но тогда это не видно. Я превращаю их в ответ. На самом деле это расширение ответа T.J.Crowder .

Вы можете найти соответствующее правило, которое заставляет Findbugs сообщать об ошибке здесь .

Вы можете запретить Findbugs сообщать об ошибках такого типа, создав xml-файл со следующим содержимым, например, filter.xml, и запустив инструмент с параметром -exclude filter.xml. Смотрите фильтры на Findbugs .

<FindBugsFilter>
  <Match>
    <Bug category="PERFORMANCE" />
  </Match>
</FindBugsFilter>
3 голосов
/ 19 декабря 2011

Переключатели переключения попадают в категорию Findbugs «хитрый код».Я думаю, что это только отмечает первое появление провала в операторе switch, чтобы сократить количество сообщений об ошибках.

2 голосов
/ 25 апреля 2017

Обычно инструментам анализа ошибок не нравится падение в коде, потому что в большинстве случаев пользователь просто забыл написать разрыв.

Не знаю, есть ли способ специально отключить предупреждение с помощью FindBugs , но Checkstyle инструмент распознает специальные комментарии, такие как / * fallthrough */ предположить, что пользователь действительно хочет, чтобы следующий код был выполнен.Размещение такого рода комментариев также улучшает читабельность.http://checkstyle.sourceforge.net/config_coding.html#FallThrough

В Java-коде также упоминается использование сквозного комментария.http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-142311.html

2 голосов
/ 19 декабря 2011

Без перерыва они будут попадать друг в друга, поэтому, если x == 0, вы пройдете весь код в каждом блоке оператора case. Поиск ошибок может быть либо ошибочным, либо ошибочным условием без прерывания, то есть что-то в case 0 приводит к тому, что что-то в case 1 ломается.

Без точного кода и ошибки я не могу помочь дальше. Преднамеренное отсутствие перерывов?

0 голосов
/ 01 ноября 2017

Если ваши дела не имеют перерыва, после того, как дело установлено, триггерный переключатель будет проходить через все дела, пока не найдет перерыв или конец дел. Если у вас есть регистр по умолчанию, он сработает, если значение вашего переключателя в этом случае foo не совпадает ни с какими другими случаями.

...