A constant expression is an expression that yields a primitive type or a String, and whose value can be evaluated at compile time to a literal. The expression must evaluate without throwing an exception, and it must be composed of only the following:
Primitive and String literals.
Type casts to primitive types or String
.
The following unary operators: +
, -
, ~
and !
.
The following binary operators: *
, /
, %
, +
, -
, <<
, >>
, >>>
, <
, <=
, >
, >=
, ==
, !=
, &
, ^
, |
, &&
and ||
.
The ternary conditional operator ?
:
.
Parenthesized constant expressions.
Simple names that refer to constant variables. (A constant variable is a variable declared as final
where the initializer expression is itself a constant expression.)
Qualified names of the form <TypeName> . <Identifier>
that refer to constant variables.
Note that the above list excludes ++
and --
, the assignment operators, class
and instanceof
, method calls and references to general variables or fields.
Constant expressions of type String
result in an "interned" String
, and floating point operations in constant expressions are evaluated with FP-strict semantics.
Constant expressions can be used (just about) anywhere that a normal expression can be used. However, they have a special significance in the following contexts.
Constant expressions are required for case labels in switch statements. For example:
switch (someValue) {
case 1 + 1: // OK
case Math.min(2, 3): // Error - not a constant expression
doSomething();
}
When the expression on the right hand side of an assignment is a constant expression, then the assignment can perform a primitive narrowing conversion. This is allowed provided that the value of the constant expression is within the range of the type on the left hand side. (See JLS 5.1.3 and 5.2) For example:
byte b1 = 1 + 1; // OK - primitive narrowing conversion.
byte b2 = 127 + 1; // Error - out of range
byte b3 = b1 + 1; // Error - not a constant expession
byte b4 = (byte) (b1 + 1); // OK
When a constant expression is used as the condition in a do
, while
or for
, then it affects the readability analysis. For example:
while (false) {
doSomething(); // Error - statenent not reachable
}
boolean flag = false;
while (flag) {
doSomething(); // OK
}
(Note that this does not apply if
statements. The Java compiler allows the then
or else
block of an if
statement to be unreachable. This is the Java analog of conditional compilation in C and C++.)
Finally, static final
fields in an class or interface with constant expression initializers are initialized eagerly. Thus, it is guaranteed that these constants will be observed in the initialized state, even when there is a cycle in the class initialization dependency graph.
For more information, refer to JLS 15.28. Constant Expressions.