Search code examples
javaperformancevariablesfinal

Effect of Java 'final' declaration for class member variables


This is more of a theory question than a solution question, so hear me out.

In C/C++ as well as PHP, you can declare constants. There are usually a couple of ways to do this (#DEFINE for example, or 'const type'...) and the ultimate effect of this is that during compilation a replace is done so that all of those named constants become literals. This helps because instead of having to access a memory location to find the data, the data is hardcoded in, but without the downside of hardcoding - recalling the value if it needs to be reused, and changing all of the instances of that value when it needs to be changed.

But Java's final declaration is slightly inscrutable; because I can create a class with unset final vars and initialize them on construction, it means that they are not precompiled as literals as far as I can tell. Other than guaranteeing that they cannot logically change afte construction, does the final declaration provide any benefit to efficiency?

References to articles are fine, as long as you make note of the part which explains what final really does and what are if any its benefits other than stopping value changes after construction.

As a corollary, is it possible to actually declare compilation-level constants in Java in any other way than simply using literals (a bad idea anyway?)


Solution

  • Java does have constant expressions. See here (link outdated, archived at archive.org) in the java language specification.

    A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

    • Literals of primitive type and literals of type String (§3.10.5)
    • Casts to primitive types and casts to type String
    • The unary operators +, -, ~, and ! (but not ++ or --)
    • The multiplicative operators *, /, and %
    • The additive operators + and -
    • The shift operators <<, >>, and >>>
    • The relational operators <, <=, >, and >= (but not instanceof)
    • The equality operators == and !=
    • The bitwise and logical operators &, ^, and |
    • The conditional-and operator && and the conditional-or operator ||
    • The ternary conditional operator ? :
    • Parenthesized expressions whose contained expression is a constant expression.
    • Simple names that refer to constant variables (§4.12.4).
    • Qualified names of the form TypeName . Identifier that refer to constant variables (§4.12.4).

    But in Java, unlike C/C++, you also have a JIT compiler, so additional inlining is possible. So the bottom line is, don't worry about until you see a real performance problem.