Итак, я работаю над этим классом, который имеет несколько статических констант:
public abstract class Foo {
...
public static final int BAR;
public static final int BAZ;
public static final int BAM;
...
}
Затем я хотел бы получить способ получить соответствующую строку на основе константы:
public static 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
об ошибке на каждой из трех меток регистра.
Я понимаю, что компилятору нужно, чтобы выражение было известно во время компиляции, чтобы скомпилировать ключ, но почему не Foo.BA_
константа?
java
compile-time-constant
Остин Хайд
источник
источник
public static final int
Они разбросаны по всему JDK, поэтому я и пошел с этим.Ответы:
Хотя они являются постоянными с точки зрения любого кода, который выполняется после инициализации полей, они не являются постоянной времени компиляции в том смысле, который требуется JLS; см. §15.28 Выражения констант для спецификации константного выражения 1 . Это относится к §4.12.4 Final Variables, который определяет «постоянную переменную» следующим образом:
В вашем примере переменные Foo.BA * не имеют инициализаторов и, следовательно, не квалифицируются как «постоянные переменные». Исправление просто; измените объявления переменных Foo.BA *, чтобы инициализаторы были константными выражениями во время компиляции.
В других примерах (где инициализаторы уже являются константными выражениями времени компиляции), объявление переменной
final
может быть тем, что необходимо.Вы могли бы изменить свой код, чтобы использовать
enum
вместоint
констант, но это приносит еще пару ограничений:default
регистр, даже если у вас естьcase
для каждого известного значенияenum
; см. Почему по умолчанию требуется для включения перечисления?case
метки должны быть явнымиenum
значениями, а не выражениями, которые оцениваютenum
значения.1 - Ограничения константного выражения могут быть обобщены следующим образом. Выражения констант а) могут использовать только примитивные типы
String
, б) разрешать основные цвета, которые являются литералами (кромеnull
) и только постоянными переменными, в) разрешать константные выражения, возможно заключенные в скобки как подвыражения, г) разрешать операторы, кроме операторов присваивания++
,--
илиinstanceof
, и д) разрешить приведение типов к примитивным типам илиString
только.Обратите внимание , что это не относится к какой - либо форме метода или лямбда - вызовов
new
,.class
..length
или массив подписки. Кроме того, любое использование значений массива,enum
значений, значений типов примитивных оболочек, упаковки и распаковки исключено из-за a).источник
Вы получаете постоянное выражение, потому что вы оставили значения вне своих констант. Пытаться:
источник
Я получил эту ошибку на Android, и мое решение было просто использовать:
вместо того
источник
Потому что они не являются константами времени компиляции. Рассмотрим следующий действительный код:
Вы можете знать только значение
BAR
во время выполнения.источник
public static final int BAR = new Random().nextInt()
работать?new Random().nextInt()
вернуть одинаковые значения?Вы можете использовать перечисление как в этом примере:
Источник: оператор Switch с enum
источник
enum Codes { CODE_A(1), CODE_B(2); private mCode; Codes(int i) { mCode = i; } public int code() { return mCode; } }
<br/> Когда я пытаюсь использовать enum в коммутаторе, я получаю ту же ошибку ... <br/>switch(field) { case Codes.CODE_A.code() : // do stuffs.. ; }
<br/> Можно решить проблему?На этот вопрос давным-давно ответили, и, вероятно, он не актуален, но на всякий случай. Когда я столкнулся с этой проблемой, я просто использовал
if
вместо этого утверждениеswitch
, оно решило ошибку. Это, конечно, обходной путь и, возможно, не «правильное» решение, но в моем случае этого было достаточно.источник
switch
это обычно быстрее, чем долгоif-else
, потому чтоswitch
проверяйте состояние только один раз , в то время какif-else
вам может потребоваться проверить все условия, прежде чем найти правильное.Иногда переменная switch также может сделать такую ошибку, например:
Чтобы решить, вы должны привести переменную к int (в данном случае). Так:
источник
Получил эту ошибку в Android, делая что-то вроде этого:
несмотря на объявление константы:
public static final String ADMIN_CONSTANT= "Admin";
Я решил проблему, изменив свой код на это:
источник
В моем случае я получал это исключение, потому что
во втором случае я вызывал константу из экземпляра,
var.MODIFICAR_KM:
но я должен использоватьVariablesKmDialog.OBTENER_KM
непосредственно из класса.источник
Если вы используете его в случае переключателя, вам нужно получить тип перечисления еще до того, как вы включите это значение в переключатель. Например :
И перечисление как:
источник
Ниже приведенный код не требует пояснений. Мы можем использовать перечисление с регистром переключения:
На основе значений классов из перечисления можно отобразить:
Надеюсь, поможет :)
источник
Я рекомендую использовать следующий способ:
источник
private Animal(String name) { this.name = name; }
Я рекомендую использовать перечисления :)
Проверь это:
Тогда вы можете использовать это так:
источник