Перечисления Java и Операторы переключения - случай по умолчанию?

Вы должны установить точное имя поля

@JsonProperty("isActive")
public boolean isActive() {
    return isActive;
}
.
56
задан KitsuneYMG 13 May 2009 в 18:42
поделиться

9 ответов

Вы всегда можете использовать шаблон Enum with Visitor:

enum Mode {
  on {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitOn();
      }
  },
  off {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitOff();
      }
  },
  standby {
      public <E> E accept( ModeVisitor<E> visitor ) {
         return visitor.visitStandby();
      }
  }

  public abstract <E> E accept( ModeVisitor<E> visitor );

  public interface ModeVisitor<E> {
      E visitOn();
      E visitOff();
      E visitStandby();
  }
}

Затем вы должны реализовать что-то вроде следующего:

public final class ModeColorVisitor implements ModeVisitor<Color> {
    public Color visitOn() {
       return getOnColor();
    }

    public Color visitOff() {
       return getOffColor();
    }

    public Color visitStandby() {
       return getStandbyColor();
    }

}

Вы бы использовали его следующим образом:

return model.getMode().accept( new ModeColorVisitor() );

Это много более подробный, но вы сразу получите ошибку компиляции, если будет объявлено новое перечисление.

71
ответ дан 26 November 2019 в 17:07
поделиться

Вы должны включить в настройках Eclipse (окно -> настройки) «Константа типа перечисления, не охваченная переключателем» с уровнем ошибки.

Выбрасывать исключение в конце метода, но не используйте регистр по умолчанию.

public String method(Foo foo)
  switch(foo) {
  case x: return "x";
  case y: return "y";
  }

  throw new IllegalArgumentException();
}

Теперь, если кто-то позже добавит новый случай, Eclipse сообщит ему, что он пропустил случай. Так что никогда не используйте значение по умолчанию, если у вас нет для этого действительно веских причин.

57
ответ дан 26 November 2019 в 17:07
поделиться

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

Например:

import java.awt.Color;

public class Test {

    enum Mode 
    {
        on (Color.BLACK), 
        off (Color.RED),
        standby (Color.GREEN);

        private final Color color; 
        Mode (Color aColor) { color = aColor; }
        Color getColor() { return color; }
    }

    class Model
    {
        private Mode mode;
        public Mode getMode () { return mode; }
    }

    private Model model;

    public Color getColor()
    {
        return model.getMode().getColor();
    }   
}

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

import java.awt.Color;
public class Test {

    enum Mode {on, off, standby;}

    class Model
    {
        private Mode mode;
        public Mode getMode () { return mode; }
    }

    private Model model;

    public Color getColor()
    {
        switch(model.getMode()) {
        case on:
           return Color.BLACK;
        case off:
           return Color.RED;
        case standby:
           return Color.GREEN;
        }
    }   
}
10
ответ дан 26 November 2019 в 17:07
поделиться

Я бы сказал, что это, вероятно, потому, что model.GetMode () может вернуть null.

6
ответ дан 26 November 2019 в 17:07
поделиться

Создайте случай по умолчанию, который вызывает исключение:

throw new RuntimeExeption("this code should never be hit unless someone updated the enum") 

... и это в значительной степени объясняет, почему Eclipse жалуется: хотя ваш коммутатор может охватывать все случаи перечисления сегодня, кто-то может добавить случай и не перекомпилировать завтра.

2
ответ дан 26 November 2019 в 17:07
поделиться

Ваша проблема в том, что вы пытаетесь использовать оператор switch как индикатор того, что ваше перечисление заблокировано.

Дело в том, что оператор 'switch' и компилятор java не могут распознать что вы не хотите разрешать другие параметры в своем перечислении. Тот факт, что вам нужны только три параметра в вашем перечислении, полностью отделен от вашего дизайна оператора switch, который, как отметили другие, должен ВСЕГДА иметь оператор по умолчанию. (В вашем случае это должно вызвать исключение, потому что это необработанный сценарий.)

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

РЕДАКТИРОВАТЬ

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

Внутренняя работа Enum и Switch полностью разделена и должна оставаться несвязанной.

2
ответ дан 26 November 2019 в 17:07
поделиться

Хорошим способом для этого было бы добавить вариант по умолчанию для возврата некоторого значения ошибки или исключения исключения и использования автоматических тестов с jUnit, например:

@Test
public void testEnum() {
  for(Mode m : Mode.values() {
    m.foobar(); // The switch is separated to a method
    // If you want to check the return value, do it (or if there's an exception in the 
    // default part, that's enough)
  }
}

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

2
ответ дан 26 November 2019 в 17:07
поделиться

Почему EclipseBuilder не распознает, что этот переключатель покрывает все возможности (или покрывает их?), И перестает предупреждать меня о необходимости возвращаемого типа. Есть ли способ делать то, что я хочу, без добавления методов в Mode?

Это проблема не в Eclipse, а скорее в компиляторе javac . Все javac видит, что у вас нет возвращаемого значения в случае, когда ничего не совпадает (тот факт, что вы знаете, что сопоставляете все варианты не имеет значения). Вы должны вернуть что-то в случае по умолчанию (или выбросить исключение).

Лично я бы просто выбросил какое-то исключение.

2
ответ дан 26 November 2019 в 17:07
поделиться

Поскольку я не могу просто комментировать ...

  1. Всегда, Всегда, Всегда использовать регистр по умолчанию. Вы будете удивлены, насколько «часто» это будет происходить (в Java меньше, чем в C, но все же).

  2. Сказав это, что, если я хочу обрабатывать только включение / выключение в моем случае. Ваша семантическая обработка javac пометит это как проблему.

0
ответ дан 26 November 2019 в 17:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: