As we all know javac inlines constants at compile time which can lead to interesting problems when only recompiling parts of an application and everyone here knows the usual solution to this (make it so that javac doesn’t understand it’s actually a compile time constant)
But if we look at the code in System.class of the oracle JDK we see the following:
public final static PrintStream out = null;
So presumably out is set by reflection or some other mechanism in the JVM initialization. But this leads to the question: Why isn’t out being inlined here? (at least I have never gotten a null pointer exception when using System.out.println()).
Does javac special case that scenario or is this actually handled by the language spec sensibly?
There are multiple outcomes of
static finalconstruct. Literals might be inlinedfor instance
static final int xxx = 1, as that’s clear but for instancestatic final int xxx = returnOne()may not be.Primitive types and String can be replaced with literals only, all other objects may not. Last but not least
System.out/inviolate JLS ( Once a final field has been initialized, it always contains the same value. ).Few ways to prevent inline:
static final String xxx="xxx".intern();orstatic final int yyy=123+return0();since the evaluation may be performed only during runtime the javac will generate GETFIELD and not BIPUSH (for int).