Тогда я хотел бы найти способ получить соответствующую строку на основе константы:
publicstatic String lookup(int constant) { switch (constant) { case Foo.BAR: return"bar"; case Foo.BAZ: return"baz"; case Foo.BAM: return"bam"; default: return"unknown"; } }
Однако при компиляции я получаю constant expression required ошибку для каждой из 3 меток case.
Я понимаю, что компилятору нужно, чтобы выражение было известно во время компиляции для компиляции switch, но почему оно не является Foo.BA_ постоянным?
Переведено автоматически
Ответ 1
Я понимаю, что компилятору нужно, чтобы выражение было известно во время компиляции для компиляции switch, но почему Foo.BA_ не является постоянным?
Хотя они постоянны с точки зрения любого кода, который выполняется после инициализации полей, они не являются константой времени компиляции в смысле, требуемом JLS; см. §15.28 Постоянные выражения для спецификации постоянного выражения1. Это относится к § 4.12.4 "Конечные переменные", который определяет "постоянную переменную" следующим образом:
Мы называем переменную примитивного типа или типа String, которая является конечной и инициализируется постоянным выражением во время компиляции (§15.28) постоянной переменной. Является ли переменная постоянной переменной или нет, может иметь последствия в отношении инициализации класса (§ 12.4.1), бинарной совместимости (§13.1, § 13.4.9) и определенного назначения (§ 16).
В вашем примере переменные Foo .BA * не имеют инициализаторов и, следовательно, не квалифицируются как "постоянные переменные". Исправление простое; измените Foo .BA * объявления переменных должны иметь инициализаторы, которые являются постоянными выражениями во время компиляции.
В других примерах (где инициализаторы уже являются постоянными выражениями во время компиляции) объявление переменной как final может быть тем, что необходимо.
Вы могли бы изменить свой код, чтобы использовать константы enum вместо int, но это накладывает еще пару других ограничений:
Все case метки должны быть явными enum значениями, а не выражениями, которые вычисляются до enum значений.
1 - Ограничения на постоянное выражение можно резюмировать следующим образом. Константные выражения a) могут использовать примитивные типы и String только, null б) разрешают только первичные значения, которые являются литералами (кроме ++) и постоянными переменными, в) разрешают константные выражения, возможно, заключенные в скобки как подвыражения, d) разрешают операторы, за исключением операторов присваивания, --, instanceof или String, и e) разрешают приведение типов только к примитивным типам или,,,.
Обратите внимание, что это не включает в себя какую-либо форму метода или лямбда-вызовов, new, .class. .length или подписку на массив. Кроме того, любое использование значений массива, enum значений, значений примитивных типов-оболочек, упаковка и распаковка - все это исключается из-за a).
Ответ 2
Вы получаете требуется постоянное выражение, потому что вы оставили значения в своих константах. Попробуйте: