Подтвердить что ты не робот

Возможно ли использовать имя класса в java switch/case statement?

Я хотел бы использовать оператор java switch, который использует имена class как константы case. Возможно ли это как-то? Или мне нужно дублировать имена классов?

Следующий код не работает из-за ошибки компилятора:

выражения case должны быть постоянными выражениями

String tableName = "MyClass1";

...

switch (tableName) {
case MyClass1.class.getSimpleName():
    return 1;
case MyClass2.class.getSimpleName():
    return 2;
default:
    return Integer.MAX_VALUE;
}

Вот онлайн-демонстрация проблемы (openjdk 1.8.0_45): http://goo.gl/KvsR6u

4b9b3361

Ответ 1

Ошибка компилятора уже говорит об этом. Метки case должны быть постоянными выражениями, и ни литераторы классов, ни результат вызова getSimpleName() на них не являются постоянными выражениями.

Рабочее решение:

String tableName = "MyClass1";
...
switch (tableName) {
    case "MyClass1":
        return 1;
    case "MyClass2":
        return 2;
    default:
        return Integer.MAX_VALUE;
}

Выражение MyClass1.class.getSimpleName() не проще, чем "MyClass1", но, конечно, не будет какой-либо проверки времени компиляции, если имена соответствуют существующим классам, а инструменты рефакторинга или обфускаторы не замечают отношения между классом MyClass1 и строковый литерал "MyClass1".

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

class MyClass1 {
    static final String IDENTIFIER = "MyClass1";
    ...
}
class MyClass2 {
    static final String IDENTIFIER = "MyClass2";
    ...
}
...
String tableName = MyClass1.IDENTIFIER;
...
switch (tableName) {
    case MyClass1.IDENTIFIER:
        return 1;
    case MyClass2.IDENTIFIER:
        return 2;
    default:
        return Integer.MAX_VALUE;
}

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

Ответ 2

Вместо использования коммутатора, почему бы не сохранить отображения на карте?

Создайте карту String для Integer и сопоставьте все имена классов с их возвращаемым значением.

По запросу, если запись не существует, верните значение по умолчанию. В противном случае верните значение на карте.

Ответ 3

Вместо Switch..case, почему бы вам не использовать If..Else. Должен работать во всех версиях Java до тех пор, пока я не узнаю.

if (tableName.equals(MyClass1.class.getSimpleName())) {
     return 1;
} else if (tableName.equals(MyClass2.class.getSimpleName())) {
     return 2;
} else {
     return Integer.MAX_VALUE;
}