javabytecodejavassistbceljavap

Make Java compiler include symbolic constant field reference in class file - possible?


It is well known that the Java compiler pulls in constant field values from other classes at compile time. The resulting class file does not contain a Constant Pool entry (of any type) for such constants.

Q: can the compiler be told to do just that? (Oracle JDK 7 would be nice)

As illustration, consider a piece of code out.println(some.other.class.FOO) that reads FOO (say, public static final int FOO = 1234) and outputs it. I am able to find the references to println no problem, but the the constant is turned into an anonymous sipush 1234.

For class-level dependency analysis, it would be great to have transparency here! Note I'm not asking to make any changed value there appear somehow in the dependent code (see loads of other SO questions on that) ...

I'm thinking about a Java Compiler API plug-in to javac, but that sounds like a bit far-fetched? Any ideas?


Solution

  • Only final variables initialized to constant expressions can be so inlined. So if you want to avoid compile time inlining like that, the obvious approach is to either make the field non-final or make the initializing expression complicated enough that it is no longer considered constant (e.g. (null == null) ? 1234 : 0)) ¹.

    Once you've already run the compiler it's too late, because the generated code is exactly equivalent to if you had inserted the constant inline instead of referencing a field.

    If you are doing static analysis on the source code, you can obviously just use any of the standard dependency finding tools.