Home » Java » Core Java » The Final Word on “final”

About Ashley Frieze

Ashley Frieze
Software developer, stand-up comedian, musician, writer, jolly big cheer-monkey, skeptical thinker, Doctor Who fan, lover of fine sounds

The Final Word on “final”

In Java, overuse of final feels like SHOUTING. It’s outdated and inappropriate much of the time.

Java and JavaScript

This is mainly about the final keyword in Java, but my opinion on its counterpart const in JavaScript has changed slightly. That I can think that const is a good thing and final is a bad thing needs some unpacking.

I like const in JavaScript because, on the whole, code that uses let or var tends to do something I disagree with. On the whole, a variable should not need reassigning after it’s first given a value. That’s not true with accumulators, or certain looping situations, but it’s more true than it’s not.

Many refactorings I propose are of the formula stop reassigning that temporary variable and delegate to a function that chooses an answer and returns it.

So my premise is that code, largely, should work on the premise that all variables are to be treated as single-assignment by default.

Let’s Enforce It Then?

Why shouldn’t we enforce it in Java?

Java already has the concept of effectively final which brings the benefits of final to constructs which need to trust something is final – i.e. lambda functions and anonymous inner classes. Essentially the compiler already knows what’s final, and for me adding final on top feels like shouting. It certainly makes the code busier… less is more, and final feels like overcrowding.

I’ll forgive const in JavaScript, partly because the linter is so keen to infer const and then demand it, and partly because JavaScript is such a loose language, you can’t trust anything without expressing it firmly. That said, I’d rather not need it!

How Can We Trust Ourselves?

Yes, but how do I know something really is final if I don’t say it’s final. What if someone changes it?

Example A:

1
2
3
4
5
6
7
8
public bool isFound(List<String> list, String value) {
    for (final String item:list) {
        if (value.equals(item)) {
            return true;
        }
    }
    return false;
}

The above code guarantees that item inside the loop can’t be redefined. Number 1 – WHO CARES!? Number 2 – the method is very short. If a Ninja came up and tried to mutate the value of item you’d notice it with short functions.

And that’s the point. If you have very short functions and keep your code modular, you can see what’s going on. You have no surprises and you can spot variables that change vs references that don’t.

Example B:

1
2
3
4
5
final boolean hadValue = isFound(myList, "Foo");
final boolean hadOtherValue = isFound(myList, "Bar");
final boolean bothFound = hadValue && hadOtherValue;
final String message = "They were both " + bothFound ? "found" : " not found";
return message;

Yawn!

1
2
boolean bothFound = isFound(myList, "Foo") && isFound(myList, "Bar");
return "They were both " + bothFound ? "found" : " not found";

Don’t make me follow your thought process a word at a time with final as the seasoning peppering the text. Make sentences of your code that explain whole thoughts and only add variables and modifiers if you need to.

Where Does Final Come In?

I use final judiciously. I should say that I make all the child-services of my bean components/services in Spring private final inside my classes, but I don’t. There’s an argument for it, namely that the wiring of the services inside an application context is innately immutable, but I tend not to. If you did, I’d not argue.

I have two key use cases where final is a MUST!

They’re both about the importance of SHOUTING and Immutability.

So you’ll always find me using private static final SomeType SOME_CONSTANT_IN_CAPITALS in class-level constants used within the class or as global variables, because they’re special and MUST be treated as constants with extra protection – the convention is strong and the danger of mistreatment much higher than a local variable in a single function.

You’ll find me wanting the immutable pattern implemented properly.

People who’ve studied for job interviews and know that final also protects things from being overridden can feel smug at this stage until I say that I’m not really that interested in that usage of it. If you’re trying to prevent a programmer from having flexibility, or trying to satisfy checkstyle or Sonar by making something final because it says so, then Meh!

But if you want truly immutable objects for some high cause, then I salute you.

Conclusion

When I start writing immutable data objects stored in caches and shared by multiple threads, you won’t be able to stop me from finaling my way through it.

I’ll move your logger and your reference data into static final BLOCK_CAPITAL_NAME d things every day of the week.

Most importantly, though: replace ALL “final ” with “” is still some of the most satisfying refactoring I’ve ever done.

Published on Java Code Geeks with permission by Ashley Frieze, partner at our JCG program. See the original article here: The Final Word on “final”

 

Opinions expressed by Java Code Geeks contributors are their own.

(+1 rating, 1 votes)
You need to be a registered member to rate this.
Start the discussion Views Tweet it!
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 our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of