Java switch statement: Constant expression required, but it IS constant
I understand that the compiler needs the expression to be known at compile time to compile a switch, but why isn't Foo.BA_ constant?
While they are constant from the perspective of any code that executes after the fields have been initialized, they are not a compile time constant in the sense required by the JLS; see §15.28 Constant Expressions for the specification of a constant expression1. This refers to §4.12.4 Final Variables which defines a "constant variable" as follows:
We call a variable, of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28) a constant variable. Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1), binary compatibility (§13.1, §13.4.9) and definite assignment (§16).
In your example, the Foo.BA* variables do not have initializers, and hence do not qualify as "constant variables". The fix is simple; change the Foo.BA* variable declarations to have initializers that are compile-time constant expressions.
In other examples (where the initializers are already compile-time constant expressions), declaring the variable as final
may be what is needed.
You could change your code to use an enum
rather than int
constants, but that brings another couple of different restrictions:
- You must include a
default
case, even if you havecase
for every known value of theenum
; see Why is default required for a switch on an enum? - The
case
labels must all be explicitenum
values, not expressions that evaluate toenum
values.
1 - The constant expression restrictions can be summarized as follows. Constant expressions a) can use primitive types and String
only, b) allow primaries that are literals (apart from null
) and constant variables only, c) allow constant expressions possibly parenthesised as subexpressions, d) allow operators except for assignment operators, ++
, --
or instanceof
, and e) allow type casts to primitive types or String
only.
Note that this doesn't include any form of method or lambda calls, new
, .class
. .length
or array subscripting. Furthermore, any use of array values, enum
values, values of primitive wrapper types, boxing and unboxing are all excluded because of a).
Constant expression required in Java switch statement
The error tells you exactly what is wrong.
Case labels must be compile-time constants. This:
case WorkflowKey.DOG_WORKFLOW.getKey():
has a method call, which is not known at compile time (according to the rules for determining what is constant).
Is WorkflowKey an enum type? Then you should just be switching on the enumerated constants:
case DOG_WORKFLOW:
You'll need a way to get the enum value from the 'process definition' instead of the String you're getting, of course.
Java swith case says Constant expression required for final field
This is not possible with a switch-statement. The switch-statement in Java is more constrained then most people know. What the comments suggest is true - your constants aren't "constant enough".
They may be final, but they are being initialized when the program starts. Java requires the switch label to be known at compile time.
The easiest solution would be to use if-else-if and I'd use the class for comparison directly instead of comparing the names character wise:
Class<?> def = definition.get(correctKey).getClass();
if (Integer.class.equals(def)) {
// your code
} else if (Double.class.equals(def)) {
// double code
} else {
// Error, not found
}
If you "need" to use a switch, then you have to define an Enum with your constants and a function mapping your input to an enum constant.
It would be interesting to know what you're trying to achieve, maybe there is another solution entirely.
Constant expression required in switch statement
It will compile if you access your static final fields statically; e.g. case ColorManager.blue:
. If you try and access then from a variable cm
, then you're preventing the compiler recognising them as compile-time constants.
Constant expression required error in switch statement with strings
case
statements have to be compile-time evaluable.
Something like Status.SUCCESS.toString()
doesn't satisfy that. A string literal, on the other hand, does.
The obvious fix is to use an an if
block.
constant expression required in switch with string
Two mistakes here:
The definition of the enum shouldn't have
class
in it. As a rule of thumb, the constants should be uppercase.enum RoleName {
WORKER,
BOSS;
}RoleName.Worker.name()
isn't allowed as acase
expression since it's not a constant expression. You could transformrequestRole.getName()
into aRoleName
and use it as aswitch
expression.switch (RoleName.valueOf(requestRole.getName())) {
case WORKER: /* ... */ break;
}
Related Topics
How to Schedule a Periodic Task in Java
Spring Security Does Not Allow CSS or Js Resources to Be Loaded
How to Get the First Day of the Current Week and Month
How to Find a Java Thread Running on Linux with Ps -Axl
Connecting to Access Database from Linux
Kafka - Broker: Group Coordinator Not Available
Webdriver for Firefox: Browser Starts W/ Empty Page, Hangs for 2 Min, Restarts, Then Test Runs. Why
Shuffle Multiple Files in Same Order
In Laymans Terms, What Does 'Static' Mean in Java
How to Pass an Array as Arguments to a Method With Variable Arguments in Java
Android Studio Google Jar File Causing Gc Overhead Limit Exceeded Error
Error:Execution Failed for Task ':App:Dexdebug'. Com.Android.Ide.Common.Process.Processexception
Java -Xbootclass Path Is No Longer a Supported Option