In the past years I have become a fan of the final keyword for variables and members in Java. But many people reading my source code opposed this view: They find that using final for every non-reassignable variable clutters the code because most variables will not be reassigned. When I recently talked to Uncle Bob and he uttered the same opinion, I decided to search the Web for reasons for and against the usage of final.

Most of the arguments stem from these source:

Most of the time, I refer to final as a modifier to class members and local variables.

When final is inevitable or very recommended

  • Constants
    By convention constants should have static and final modifiers. 

    private static final int CONSTANT = 1;
  • Inner classes:
    Inner classes can only access local variables when they are final.
  • Utility classes:
    Utility classes should be final and have a private constructor: 

    public final class CollectionUtils {
        private CollectionUtils() {
            new UnsupportedOperationException("private class");
        }
    }

 Pro final

  • Easier to understand during maintenance and debugging
    It is clear which variables remaing the same within the current scope. final reduces complexity.
  • Avoids NullPointerExceptions
    In order to check whether a variable is null or not, you only have to check its initialization.
  • Color patterns
    After a while, the color patterns that result from the frequent finals may help to navigate through the code.
  • Compiler can optimize
    Some people argue that the compiler is able to optimize when final is used.
  • Immutabilitiy
    Using final is necessary (but not sufficient) to enforce immutability. 

    • Use Collections.unmodifiable… to make immutable collections
    • final fields need to be set in the constructor. Some frameworks (such as UIMA) expect variables to be initialized in an initialize method. In this case, we cannot use final.
  • Fosters thread-safety
    Synchronizing on final variables is safer.
  • Extension points:
    Marking methods as final allows to quickly find out, which methods serve as extension points. Joshua Bloch’s Effective Java even suggests to make as many methods (and classes) final as possible.
  • Discourages overbroad scoping
    Every local variable should serve one purpose. Using final, we can avoid the reusage of dummy variables such as in the following example (taken from Stackoverflow): 

    String msg = null;
    for(int i = 0; i < 10; i++) {
        msg = "We are at position " + i;
        System.out.println(msg);
    }
    msg = null;

Contra final

  • Clutters the code
    Normally, most (local) variables are assigned only once and are thus eligible for bearing final in front of them.
  • Hard-to-read method signatures
    When you make a method and all of its parameters final, the method signature is unlikely to fit one line even with two parameters. This makes the method signature hard to read.
  • Final can be replaced with static code checkers…
    … at least in some places: IDEs and code checkers (PMD, Style check,…) check that method parameters are not re-assigned. However, some of them will suggest to make method parameters final :-)
  • final is not const
    Objects that are labeled with final can still be modified if they have non-immutable members. If you are accustomed to the const keyword in C/C++, this behavior is misleading.
  • May slow down development
    While coding, you may change your mind on whether a certain variable is final or not. Every time, you change your mind, you have to add or remove the final. However, many IDEs support you in both directions: Eclipse can add final where possible on saving and, vice versa, when you try to re-assign a final variable, it will offer you to make it non-final.