Search code examples
javacompile-time-constant

Avoiding Replacing Constant Reference With a Literal When Compiled


I've discovered that when a constant (static final, initialized at compile time) is declared in one project, references to it in another project are replaced by a literal when compiled.

It seems the only way to avoid this and have references refer to the constant field rather than the literal is to declare the constant in a class (as opposed to an interface) and omit "final," e.g.:

public class MyClass {
   public static String MY_CONSTANT = "The constant value";
 }

Unfortunately I coded an interface full of constants before I understood this, and now to effect a change in a constant, we have to identify all projects that refer to it and recompile them. I'm afraid something will slip through.

Also, a constant without the "final" modifier isn't exactly constant, is it?

Is there a compile option that can suppress the replacement of constant references by literals?


Solution

  • You just need something that isn't a compile-time constant expression. For example, method invocations aren't. So just adding .intern() at the end of each literal will make it escape the rules. Then each referring site will have to ensure the target type is initialized and read the current value.

    A compiler option that changes this behavior is impossible because it would violate the Java Language Specification.