Search code examples
javanullbytecode

Why isn't null a compile time constant?


So if I have a static final Object CONSTANT = null, for some reason if I reference that in another piece of code like doSomething(CONSTANT), it won't be in-lined onto the code during compilation. So instead of being doSomething(null) after being compiled, it would be doSomething(CONSTANT).


Solution

  • Your CONSTANT is not a compile time constant because the JLS says it is not. The only types that can be used in constant expressions are the primitive types and String.

    The sense of it is that an Object instance (in general) has a semantically significant object identity that distinguishes it from other Object instances. This Object identity cannot be encoded in a class file ... or at least, it can't be encoded with the current classfile formats. (And if it could, there would be all sorts of other problems ...)

    The value null could (in theory) be handled as a special case, except that there is not a great deal of point. Specifically, you can't use null in any of the contexts where a "compile time constant" is required (or advantageous) from the linguistic perspective. For instance:

    • You can't have null as a case expression.
    • Since == for reference types is not a constant expression, you can't use it for the Java "conditional compilation" idiom involving an if with a constant expression as a condition. (And besides null == null is not a useful condition ...)

    As far as inlining is concerned, while the "constant" cannot be inlined in the bytecodes (because of the JLS rules about what a "constant expression" is), the JIT compiler's optimizer would be permitted to do this, and may actually do it ... if there are tangible performance benefits.

    Reference: