Почему в операторе switch все дела выполняются? - PullRequest
10 голосов
/ 09 ноября 2011

У меня есть этот код с оператором switch, который я получил из этого поста , и он работает абсолютно нормально:

String getOrdinal(final int day) {
    if (day >= 11 && day <= 13) {
        return "th";
    }
    switch (day % 10) {
        case 1: return "st";
        case 2: return "nd";
        case 3: return "rd";
        default: return "th";
    }
}

Но если я изменю его на что-то вродезатем он прерывается, так как все случаи, кроме case 1, выполняются:

  static String getOrdinal(final int day) {
    StringBuilder ordinalBuilder = new StringBuilder();
    ordinalBuilder.append("<sup>");
    if (day >= 11 && day <= 13) {
        ordinalBuilder.append("th") ;
    }
    switch (day % 10) {
        case 1: ordinalBuilder.append("st");
        case 2: ordinalBuilder.append("nd");
        case 3: ordinalBuilder.append("rd");
        default: ordinalBuilder.append("th");
    }
    ordinalBuilder.append("</sup>");
   return ordinalBuilder.toString();
 }

Это печатает 2<sup>ndrdth</sup>, когда я передаю 2.Я попытался сменить компоновщик на буфер, но получил тот же ответ ... Может ли это быть ошибкой или я делаю какую-то ошибку?

Ответы [ 5 ]

41 голосов
/ 09 ноября 2011

Это ошибка в вашем коде. Вы забыли вставить break после каждого case:

switch (day % 10) {
    case 1: ordinalBuilder.append("st"); break;
    case 2: ordinalBuilder.append("nd"); break;
    case 3: ordinalBuilder.append("rd"); break;
    default: ordinalBuilder.append("th"); break;
}
22 голосов
/ 09 ноября 2011

Я не вижу здесь никакой ошибки, по крайней мере, не в том, как работает язык. Поведение оператора switch по своей конструкции заключается в том, что он начнет выполнять операторы с меткой case, которая соответствует аргументу, а затем продолжится до конца блока. Так

switch (x) {
    case 1:
        // do thing 1
    case 2:
        // do thing 2
    case 3:
        // do thing 3
    default:
        // do nothing
}

будет делать обе вещи 2 и 3, если x равно 2, и будет делать вещи 1, 2 и 3, если x равно 1.

Чтобы получить поведение, которое вы, вероятно, ищете, заканчивайте каждый case с break:

switch (x) {
    case 1:
        // do thing 1
        break;
    case 2:
        // do thing 2
        break;
    case 3:
        // do thing 3
        break;
    default:
        // do nothing
        break;
}

(строго говоря, break в самом конце не нужен, но я часто употребляю его по привычке).

Причина, по которой у вас не возникло этой проблемы в первом примере кода, заключается в том, что return похож на супер- break: он имеет тот же эффект, что и break, а именно завершает выполнение в блоке switch , но это также завершает выполнение всего метода.

9 голосов
/ 09 ноября 2011

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

6 голосов
/ 09 ноября 2011

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

Если вы не используете break, компилятор считает, что он можетпродолжить выполнение всех дел до конца программы.

3 голосов
/ 09 ноября 2011

Первая версия возвращается, прежде чем продолжить в операторе case.Вторая версия нуждается в перерыве;заявление, чтобы получить то же поведение.

...