The Java compiler does not optimize static final strings. Why?

The Java compiler does not optimize static final strings. Why? … here is a solution to the problem.

The Java compiler does not optimize static final strings. Why?

I have the following code in my application:

  public static final boolean DEBUG = true;
  public static final boolean REL = ! DEBUG;

private static final String DEBUG_OR_RELEASE = (REL) ? "RELEASE_VER" : "DEBUG_VER";

I

thought the Java compiler would completely eliminate the “DEBUG_VER” string from the generated .apk file (when exported via Proguard), but when I checked the .apk file, I saw the string inside the "DEBUG_VER“.

Why? What am I missing? What am I doing wrong?

Solution

Compile to Java bytecode is not optimized (except for a few exceptions).

To simplify, many books say that the “compile” phase is when optimization occurs, but this is wrong. When optimization does occur, it is when the JVM processes the bytecode file. So to clear it: optimization can happen when compiling bytecode into machine-native code, which is done by JVM tools.

Sometimes there is no optimization at all (the JVM works in interpreted mode). Sometimes JIT (just-in-time compiler) does some optimizations. Sometimes, the adaptive optimizer takes care of optimization (not only optimization, but also analyzing code execution as it performs other things).

Finally, there is nothing wrong with your files. This is how the Java world works.

“But why?” – You may ask. The reason for keeping this “useless” information in bytecode is that you can never be sure how much code can be eliminated so that the optimizations provided by different JVMs can still work efficiently. The best thing to do is to leave no information and let the optimizers do their job.

Related Problems and Solutions