Where is the description of Constant Folding in the Java Language Specification, Java SE 11 Edition (JLS SE 11)?

Tags: , , , ,



As far as I know, Java deals with constant variables §4.12.4 by constant folding in compile time. I’ve tried my best, but I couldn’t find its description from JLS. Could anybody tell me where I could find official description of the constant folding process for Java 11?

Answer

The specification does not use the term Constant Folding.

It has the definition of Constant Expressions

A constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

[…]

Constant expressions of type String are always “interned” so as to share unique instances, using the method String.intern.

A constant expression is always treated as FP-strict (§15.4), even if it occurs in a context where a non-constant expression would not be considered to be FP-strict.

Constant expressions are used as case labels in switch statements (§14.11) and have a special significance in assignment contexts (§5.2) and the initialization of a class or interface (§12.4.2). They may also govern the ability of a while, do, or for statement to complete normally (§14.21), and the type of a conditional operator ? : with numeric operands.

The last part does already point out where precalculation of constant expressions is mandatory. When it comes to case labels, the compiler is required to report duplicates, hence, it must calculate the values at compile-time. When calculating loops, it must calculate constant boolean expressions to determine code reachability.

Likewise, initializers need precalculation to determine the correctness. E.g. short s = 'a' * 2; is a correct declaration, but short s = Short.MAX_VALUE + 1; is not.

A well known use case of constant expressions is the initializer of constant variables. When reading a constant variable, the constant value will be used instead of reading the variable, compare with the Q&A “Does the JLS require inlining of final String constants?”

But this does not imply that “constant folding” is mandatory. In theory, a conforming implementation still could perform the calculation of the constant expression as written in the variable initializer at every place where the variable is used. In practice, the bytecode format leads to a constant folding behavior. The ConstantValue attribute which is used to record the value of a constant variable in bytecode can only hold a precalculated value. When compiling against an already compiled class file, the original expression of a constant variable is not available to the compiler. It can only use the precalculated value.

Likewise, compiling a switch instruction is normally done using either, the tableswitch or the lookupswitch instruction, both requiring precalculated int values for the case labels. A compiler would have to go great length to implement a different strategy.

Also, the compiled format for annotation values can only hold precalculated expressions.



Source: stackoverflow