Когда использовать оператор switch в Java - PullRequest
13 голосов
/ 20 января 2010

Я ценю, что все, что может быть сделано с помощью параметра switch, может быть сделано оператором if else.

Но существуют ли стилистические правила, когда нужно использовать переключатель, а не как статут?

Ответы [ 16 ]

1 голос
/ 20 января 2010

Переключатель и перечисления.

Если значение enum, которое вы тестируете, по какой-либо причине может быть null, то его включение в оператор switch приведет к возникновению исключения NullPointerException. Не глядя на байт-код, это немного сбивает с толку, что так и будет.

Объяснение: перечисления являются синтаксическим сахаром, введенным в 1.5. Оператор switch по-прежнему работает с хорошими олетами, но используемые им значения являются порядковыми номерами, присвоенными enum. Чтобы получить порядковый номер, значение перечисления ДОЛЖНО быть ненулевым.

if statement, с другой стороны, был бы рад принять null для значения enum и просто не прошел бы тест без NPE.

1 голос
/ 20 января 2010

Прежде всего, оператор switch должен быть применимым. Если переключатель основан на значении переменной, то его можно использовать. Если оно основано на сложном логическом выражении AND / OR / NOT, которое варьируется для каждого условия, вы вообще не сможете его использовать.

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

0 голосов
/ 30 ноября 2015

Я согласен с ответом x4u .

Кроме того, есть еще один случай, не упомянутый, но я думаю, что лучше использовать if - else блоков, чем switch: когда проверяются дополнительные условия в каждом из case блоков. с if блоками. Я вижу эту смесь все время в существующем коде.

Например, я только что наткнулся на этот код, который имеет switch в строке type, а затем проверяет вторую строку extension, используя if в обоих case инструкциях.

 public abstract class Temp {

    boolean valid;

    public Temp() {
        String type = getType();
        String extension = getFilenameExtension();
        switch(type) {
            case "Image File": {
                if(!".jpg".equals(extension) && !".png".equals(extension)) {
                    warnWrongImageFormat();
                    valid = false;
                }
                break;
            }
            case "Zip File": {
                if(!".zip".equals(extension)) {
                    warnWrongZipFormat();
                    valid = false;
                }
                break;
            }
            default: {
                valid = true;
                break;
            }
        }
    }

    abstract String getType();
    abstract String getFilenameExtension();
    abstract void warnWrongImageFormat();
    abstract void warnWrongZipFormat();
}

Вместо этого гораздо чище и менее сложно уменьшить это значение до одного if else

public abstract class Temp {

    boolean valid;

    public Temp() {
        String type = getType();
        String extension = getFilenameExtension();
        valid = true;
        if("Image File".equals(type) && !".jpg".equals(extension) && !".png".equals(extension)) {
            warnWrongImageFormat();
            valid = false;
        }
        else if("Zip File".equals(type) && !".zip".equals(extension)) {
            warnWrongZipFormat();
            valid = false;
        }
    }

    abstract String getType();
    abstract String getFilenameExtension();
    abstract void warnWrongImageFormat();
    abstract void warnWrongZipFormat();
}
0 голосов
/ 20 января 2010

Переключатель имеет два существенных недостатка:

  • ограничено примитивными типами и перечислениями
  • Вы должны помнить "break", что может привести к не очень очевидным ошибкам

Часто переключатель является признаком плохого дизайна ОО, потому что вам лучше использовать полиморфизм.

Единственное возможное преимущество коммутатора в том, что он более читабелен. Но это

switch (i) {
  case 1:
    // do something
    break;
  case 2:
    // do something
    break;
}

более читабельно, чем это:

if (i == 1)
  //do something
else if (i == 2)
  // do something else

Я бы сказал: нет! И у вас не будет недостатков в переключателе.

Мое предложение: старайтесь избегать переключения.

0 голосов
/ 20 января 2010

Как и в других языках, таких как C или C ++, операторы switch полезны, когда вы хотите сравнить данную переменную со списком возможных значений и выполнить действие в зависимости от этих значений. Это гораздо лучше, чем если бы еще заявления.

0 голосов
/ 20 января 2010

если у вас слишком много условий для проверки аналогичного типа, вы можете перейти на переключатель.

...