janino-compiler / janino

Janino is a super-small, super-fast Java™ compiler.
http://janino-compiler.github.io/janino
Other
1.25k stars 208 forks source link

How to disable inline variables feature #184

Closed wangkaish closed 1 year ago

wangkaish commented 1 year ago

Hi @aunkrig , I have a class B

class B {
  public static final String NAME = "123";
  public String sayHi() {  
    return "Hi: " + B.NAME;
  }
}

In compile result, sayHi will be

  public String sayHi() {  
    return "Hi: 123";
  }

How to disable this feature?

I want to speed up compiling incrementally, when compiling some class like B with reference to the static constant, if the static constant is modified out, but because the B is not compiled, the B is still using the old constant value which causes the error to happen.

aunkrig commented 1 year ago

Hey Kai, what you observe is, strictly speaking, not a bug or problem, but a feature of the Java programming language, see JLS11 13.4.9:

If a field is a constant variable (§4.12.4), and moreover is static, then deleting the keyword final or changing its value will not break compatibility with pre-existing binaries by causing them not to run, but they will not see any new value for a usage of the field unless they are recompiled. This result is a side-effect of the decision to support conditional compilation (§14.21). (One might suppose that the new value is not seen if the usage occurs in a constant expression (§15.28) but is seen otherwise. This is not so; pre-existing binaries do not see the new value at all.) The best way to avoid problems with "inconstant constants" in widely-distributed code is to use static constant variables only for values which truly are unlikely ever to change. Other than for true mathematical constants, we recommend that source code make very sparing use of static constant variables.

In other words: The Java compiler is free to inlines any constant, thus eliminating the runtime dependency on the other class, so it doesn't recompile the class if the other class changes.

Couldn't you, as recommended, remove the static (or the final) keyword from your variable declaration? That would be the "natural" way to avoid the constant inlining process.

wangkaish commented 1 year ago

Understand, thank you.