Я думаю, что главная проблема этого вопроса в том, что ваша IDE сообщает вам, что вы пропускаете значения enum в выражении switch. И спрашивает вас, хотите ли вы добавить их, а не ваш компилятор. Это, конечно, не гарантирует, что пользователь вашего класса enum должен использовать каждое значение.
Есть подход, упомянутый Джошуа Блохом в его книге «Эффективная Java» (глава Emulated extensible enum using an interface
), которую можно изменить для работы с переключателем, показанным здесь: Java Enum Switch . Но я думаю, что решение для переключения не не обеспечивает полную безопасность использования всех перечислений.
Но так как вы хотели узнать, существует ли решение с использованием строк, мы также можем попробовать использовать функциональный подход, как показано здесь: Функциональный подход с помощью Enum Switch и заставить его работать со строковыми полями вместо перечислений.
Это может выглядеть следующим образом:
public class Direction {
private static final String NORTH = "north";
private static final String SOUTH = "south";
private static final String EAST = "east";
private static final String WEST = "west";
public interface SwitchResult {
void NORTH();
void SOUTH();
void EAST();
void WEST();
}
public static void switchValue(String direction, SwitchResult result){
switch (direction){
case NORTH:
result.NORTH();
break;
case SOUTH:
result.SOUTH();
break;
case EAST:
result.EAST();
break;
case WEST:
result.WEST();
break;
}
}
public static void main(String[] args) {
String direction = "west";
Direction.switchValue(direction, new SwitchResult() {
@Override public void NORTH() {
System.out.println("this time north");
}
@Override public void SOUTH() {
System.out.println("this time south");
}
@Override public void EAST() {
System.out.println("this time east");
}
@Override public void WEST() {
System.out.println("this time west");
}
});
}
}
Как вы можете видеть в методе main, если вы хотите вызвать функцию switchValue, вы должны передать вашу строку и реализацию вашего интерфейса, что гарантирует вам возможность переопределить все возможности. В обмен на это код очень избыточен.
Этот подход можно использовать, если у вас есть доступ только для чтения к классу, который предлагает набор значений String, и вы хотите построить оператор switch вокруг него. В любом другом месте вы действительно должны придерживаться подхода, использующего перечисления.
Если вы хотите использовать сторонние инструменты, чтобы действительно убедиться в том, что вам не нужно писать какой-либо избыточный шаблонный код, взгляните на:
- FindBugs SF_SWITCH_NO_DEFAULT : Но это относится только к ветви по умолчанию оператора switch.
- @ EnumMapper : процессор аннотаций, который проверяет во время компиляции, что все константы перечисления обрабатываются