Java Code Style: The Final Decision

Isn’t it funny how the alleged most unremarkable things can lead to controversial discussions or sometimes even heated debates with hardend fronts? I witnessed on several occassions for example, how the usage of the keyword final triggered quite passionate arguments. And for an outside observer this might have looked as if the ultimate decision about being evil or divine was at stake.

However it must be said in all fairness, most of the possible final use cases hardly fit into a simple right or wrong pattern. The choice about to use or not to use rather depends on the individual emphasis of often contradictorily intentions.

Seeking for advice in literature, the only halfway common ground seems to be the final constants definition…

class Foo {
  public static final String CONSTANT = "constantValue";
}

… and Joshua Bloch’s Item 15: Minimize mutability1, where he recommends to make all fields of an immutable class final and to ensure, that the class cannot be extended (whereas the latter does not mandatorily need to be achieved by final):

public final class Foo {

  private final int value;

  public Foo( int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }

  [...]
}

From there opinons diverge. Robert Simmons jr. has dedicated an entire chapter on the final keyword in his book Hardcore Java2, which he concludes with the strong advice to ‘spread final all over your code’. This well written chapter contains a lot of insights about the advantages of converting logical errors into compile time errors by declaring variables, parameters, methods or classes final.

On the other hand Robert C. Martin explicitly disagrees with the following statement: ‘there are a few good uses for final, such as the occasional final constant, but otherwise the keyword adds little value and creates a lot of clutter’3. Continuing he explains, that the kind of errors final might catch are usually covered by his unit tests.

While I tend to agree with Martin I would not say Simmons is generally wrong. In the past I actually used the final keyword often by myself with the intent to avoid programming mistakes or misuse. One reason for changing my mind, though, is probably my shift to the TDD approach a couple of years ago.

By doing so I noticed – additionally to Martin’s argument – achieving test isolation via collaborator mocks gets quite more tricky, if the collaborator class or some of its methods are declared as final. As testing hardly can be considered misuse, it made me think of the far reaching consequences such declarations can imply. I got aware of how difficult it is to foresee, that there will be no valid use case, which would justify extension and overriding.

On the contrary, confronted with final methods or classes, people sometimes get quite inventive to somehow circumvent the restrictions, making things probably worse than e.g. class extension would have been. Because of this I nowadays usually refrain from using the keyword on classes and method declarations and confine myself to a not-to-be-intended-for-sub-classing note or the like in the documentation.

Before this post is drawing to its end, I like to share a last thought regarding the cluttering topic mentioned above. To do so please have a look at the following code, which relies on final for method scoped variables and parameters:

public void doit( final String message ) {
    final int value = calculate();
    final Item item = create( value, message );
    executorService.submit( new Runnable() {
      public void run() {
        handle( item );
      }
    } );
  }

Although the code is quite useless and can be arranged differently, it reflects some real coding style with respect to final I stumbled across recently. While this style prevents reassignment of local variables on accident, it also disguises the fact, that one final declaration is actually mandatory. This is because the variable item is used within the annonymous Runnable implementation. The next snippet gets rid of the unneeded declarations to stress the difference:

public void doit( String message ) {
    int value = calculate();
    final Item item = create( value, message );
    executorService.submit( new Runnable() {
      public void run() {
        handle( item );
      }
    } );
  }

Weighing the pros and cons I prefer the last variant, but I assume depending on your personal point of view, the capabilities of your IDE to quit local reassigments with warnings, the coding conventions of your team, and, and, and, you will probably have good reasons to choose either the first or the second style or even favor a mix of both.

Which leads me to the final conclusion, that the controversy will rage on!

  1. Effective Java (Second Edition), Chapter 4 – Classes and Interfaces, Joshua Bloch, 2008
  2. Hardcore Java, Chapter 2 – The Final Story, Robert Simmons jr., 2004
  3. Clean Code, Chapter 16, Refactoring SerialDate, Robert C. Martin, 2009

 

Reference: Java Code Style: The Final Decision from our JCG partner Frank Appel at the Code Affine blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

2 Responses to "Java Code Style: The Final Decision"

  1. veggen says:

    When writing any code, one can never imagine the scenario future users and maintainers will run into. For this reason, one should never assume noone will ever need to extend/override something. Putting finals all over is believing in own omnscience, and in my opinion wrong by definition. Intended usage should be communicated through comments even if it initially appears dirtier, and the user should be allowed to make use of the existing code in any way they see fit. The code was written for them anyway.

  2. Tobias B. says:

    There is one more thing to say about the final modifier.
    If you use it on methods it does impact the performance of your Program!
    The Compiler is then no longer forced to look in further extended classes if the method has been overridden.

Leave a Reply


three + = 4



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close