Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

All About 'Finals'

DZone's Guide to

All About 'Finals'

This overview of the final keyword and immutability covers the final keyword and its use in lambda expressions, code in general, and advice about using it more often.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

A variable can be declared final. A final variable may only be assigned to once. It is a compile-time error if a final variable is assigned to unless it is definitely unassigned immediately prior to the assignment.

After the assignment of any final variable, it can never be altered. If the variable refers to any instance of any object, it will continue to refer to the same object instance, however, the internal state of the object can be modified.

Effectively Final

A variable can also be considered as effectively final if and only if:

  1. It is not declared as final
  2. The assignment occurs once

I find the simplest way to explain effectively final is to imagine adding the final modifier to a variable declaration. If, with this change, the program continues to behave in the same way, both at compile time and at runtime, then that variable is effectively final.

Use in Lambda Expressions

Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final, or a compile-time error occurs where the use is attempted.

The restriction of local variable capture to effectively immutable variables is intended to direct developers’ attention to more easily parallelizable, naturally thread-safe techniques. Mutable fields are always a potential source of concurrency problems if not properly managed. Disallowing field captures by lambda expressions would reduce the usefulness without doing anything.

Use of the Final Keyword

In my opinion, it is a better practice to mark local variables, method arguments, and field variables as final whenever appropriate. It warns other developers to not accidentally modify a value. Apart from this, it signals the compiler to optimize the class file. There are lots of arguments against this statement saying that it is not true that use of the final keyword in a source file enables optimization of the class file. I strongly advise you to have a look at Hardcore Java written by Robert Simons Jr. in which the use of final keyword and its optimizations have been detailed.

I feel the application of final keywords makes the intent of the code clear to any developer. Making a variable final relieves the programmer of excess stress to scan the code to see if the variable has changed anywhere after its initialization. It is also much safer than non-final variables in terms of maintaining states in a multithreaded environment.

According to the detailed benchmark as provided by RustyX in a StackOverflow thread, the following program demonstrates a noticeable performance gain:

public class FinalTest {

    public static final int N_ITERATIONS = 10_00_000;

    public static String testFinal() {
        final String a = "a";
        final String b = "b";
        return a + b;
    }

    public static String testNonFinal() {
        String a = "a";
        String b = "b";
        return a + b;
    }

    public static void main(String[] args) {
        long tStart, tElapsed;

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method with finals took " + tElapsed + " ms");

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testNonFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method without finals took " + tElapsed + " ms");

    }

}


The result was quite outstanding:

Method with finals took 5 ms
Method without finals took 273 ms


I also personally prefer to lean toward the use of immutable classes and the use of the final keyword as instance variables to signify this. According to Joshua Bloch in Effective Java.:

Immutable classes are easier to design, implement, and use than mutable classes. They are less prone to error and are more secure. Furthermore, an immutable object can be in exactly one state, the state in which it was created. Mutable objects, on the other hand, can have arbitrarily complex state spaces.

Static Code Analysis Tools

Static Analysis tools like PMD are one of the biggest proponents of the usage of the final keyword whenever appropriate. For more information, have a look at this. FindBugs and CheckStyle are configured to warn about variables if the final keyword is missing. I have found this link that supports the use of final keywords in CheckStyle:

Changing the value of parameters during the execution of the method’s algorithm can be confusing and should be avoided. A great way to let the Java compiler prevent this coding style is to declare parameters final.

Eclipse Save Action

Eclipse IDE provides useful Save Actions Preferences page that lets you apply changes primarily focused on optimizing source code. One of the Save Actions is the application of final keywords to variables whenever appropriate.

Conclusion

In terms of clear design and readability, I support the use of the final keyword in source files, whereas a few of my fellow Java developers would disagree with me due to the visual clutter that it introduces. I agree that, seemingly, the use of final keywords in local variables, instance variables, method arguments, constructor arguments, and catch clauses could increase visual clutter and verbosity. But if anything that can assist any future developer or any maintainer perform their jobs faster, reliably and efficiently, we should make use of that.

But, of course, it’s all personal preference. I would love to hear your opinions on this regard.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
java final keyword ,immutable classes ,java performance ,java ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}