SonarQube - Java-правило "S128" - Почему правило жалуется на то, что оператор break отсутствует, когда это явно не нужно?

Я не могу понять, почему Sonar продолжает жаловаться на то, что у меня "нет заявления о разрыве", даже если это не нужно.

Мой переключатель:

    public static String lookupVoyageId(String referenceNumber, String sender) {
    switch (sender) {
        case "400_HGENT":
        case "200_HAPEN":
        case "500_HOOST":
            Preconditions.checkArgument(referenceNumber.contains("-"));
            return referenceNumber.split("-")[0];
        case "600_HZEEB":
            Preconditions.checkArgument(referenceNumber.length() >= 6);
            return referenceNumber.substring(0, 6);
        case "800_BVL":
            throw new TransferException("This reference number for IBIS isn't according to the requirements. Can't implement it yet.");
        case "MCCD":
            throw new TransferException("This reference number for MCCD isn't according to the requirements. Can't implement it yet.");
        default:
            throw new TransferException("The sender (" + sender + ") couldn't be identified.");
    }
}

и сонар продолжает давать мне критическое: "Оператор switch не содержит разрыва"

Почему это? Мне не нужны какие-либо перерывы в этом переключателе?

Я знаю, что это может быть конкретный случай, но я не могу найти что-либо в Интернете.

Ответ 1

Примечание. Я не пытаюсь ответить на вопрос. Но давайте посмотрим, что говорит это конкретное правило.

Правило S128 говорит:

Ключи коммутаторов должны заканчиваться безусловным оператором "break"

Когда выполнение не заканчивается явно в конце коммутатора case, он продолжает выполнять утверждения следующего случая. Хотя это иногда преднамеренно, часто это ошибка, которая ведет к неожиданному поведению.

Несоответствующий пример кода

switch (myVariable) {
  case 1:                              
    foo();
    break;
  case 2:  // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ?
    doSomething();
  default:                               
    doSomethingElse();
    break;
}

Соответствующее решение

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

Исключения

Это правило ослабляется в следующих случаях:

switch (myVariable) {
  case 0: // Empty case used to specify the same behavior for a group of cases.
  case 1:                               
    doSomething();
    break;
  case 2:  // Use of return statement
    return;
  case 3:   // Use of throw statement
    throw new IllegalStateException();
  default:  // For the last case, use of break statement is optional
    doSomethingElse();
}

Ссылки: https://sonar.spring.io/rules/show/squid:S128?layout=false

Ответ 2

Sonar не может знать, работает ли фрагмент кода по назначению. Он не может понять бизнес-логику вашего приложения, поэтому он не знает, что ваш код предполагается работать таким образом.

Какой сонар может знать, что этот шаблон (т.е. оператор switch, который проваливается) является распространенным источником труднодоступных ошибок. По этой причине Sonar как инструмент качества кода препятствует работе таким образом, как часть общей цели сокращения распространенных ошибок.