By day, I write Java code in the enterprise world. When I compare my code to others’ code, I sometimes feel like I excessively use the
final keyword. It seems that most developers will only use
final for a constant declaration such as
However, I would bet that 95% of my my local variables are declared
final. Am I going overboard?
Saving another developer (or future you) some thinking
Consider a typical line of code that does not use
There are a few reasons this makes me cringe:
- This forces someone reading your code to perform a mental shift. This developer has grown to know and love
path, and now it isn’t what it used to be. Humans aren’t nearly as good at context shifting as we think we might be. Sure, in this trivial example, the harm seems minimal, but the more shifting references in the code, the harder it is to keep track of what is what.
- Being more explicit would make your code easier to understand. Why not give other developers a better clue as to what’s going on?
Encouraging best practices
You’ll find that if you consistently use
final variables, the compiler will prevent you from shooting yourself in the foot from a maintainability perspective.
final will encourage you to use the narrowest scoping possible.
1 2 3 4 5 6 7 8 9 10 11 12 13
What’s wrong with that code? Okay, you probably realized that if the address is null we will register the user with the city of a previous user in the list. However, in order to realize this, you had to think and scrutinize the code at least a little bit. If you were in the habit of using
final variables, things would look more like this:
1 2 3 4 5 6 7 8 9 10 11 12
The version using
final won’t let you get away with letting a value persist across iterations. It also won’t leave any broadly-scoped variables hanging around once your code is done with the loop. In my opinion, it is also easier to digest. You immediately see what the value of each variable is, and because you know the reference won’t change, you don’t have to think much at all about what is happening.
Complicated logic trees
your someone else’s code has some complicated logic tree with
else if, and
else branches of various levels, it can be tough to track down blocks that might execute twice and thus reassign a variable. If those variables are declared
final, the compiler will make sure that these variables don’t get assigned twice. Here is where you might say
But sometimes I know two blocks are mutually exclusive but the compiler can’t tell.
This could definitely be the case; I won’t say you are wrong. But I will ask a couple questions:
- Does everyone else who will ever see this code know this same magical fact that you do? Maybe others aren’t nearly as smart as you are and would benefit from you making the mutual-exclusivity explicit.
- Can you restructure your logic so that the compiler knows that only one of these blocks can execute? This will make your code much less error prone.
Free minor optimizations
The compiler and JVM can make minor optimizations on
final variables. Sure these are small gains, but I’ll take them since they come free with the other benefits of using
As you most likely know if you have up to this point,
final has more than one meaning in Java. I think that most Java developers can understand use cases for
final classes, methods, and fields, even if they don’t use them regularly. However, I think they belittle the utility of
final local variables. Several developers have told me
Sure, I should probably make more of my variables final, but it isn’t worth the verbosity.
I agree that the verbosity is a shame. I think that in Java variables should be
final unless declared otherwise (have I mentioned that Scala is my hobby language?). We are stuck with
final being opt-in instead of opt-out, so here are my closing points to ponder:
- Are you concerned about typing the extra 6 characters (including space) for your variables?
- Which is going to end up taking more time, typing the extra characters or debugging problems stemming from broadly-scoped variables or inadvertent reasssignments?
- Are you concerned about extra noise in your code that distracts from the real logic?
- This is a valid concern. But I think that the extra verbosity helps by saying “Look, I am a simple assignment. You don’t have to worry about me changing down the line. You can focus on more complicated things.”