val vs final

One of the things I see happening in Java code more frequently, is the appearance of additional final access modifiers on local variables. On member fields I really love the final access modifier because it makes my life as concurrency bug searcher, a lot easier. But I also see them more often on local variables like this:

void foo(final int x){
	final int z = 10;

Personally I find the added value of the final access modifier on these variables limited. In Scala I would go for it since it is just as easy to write a ‘val’ instead of a ‘var’ and a functional style of programming is promoted. But in Java the code tends to get ‘messy’ and method signatures are more often getting too long to place on a single line, which reduces readability.

That is why I’m questioning myself: how many bugs did I had in my 10+ years as developer, caused by a reassignment to a local variable? Perhaps I had them in the beginning, but I don’t know how long it has been. So why should a ‘fix’ be done on a non existing problem? And I like my methods short, so it is easy to see if something smelly is going on.

So unless it is some compiler optimization that is not triggered otherwise, or the variable is used in an anonymous inner class, I don’t see the added value of having final local variables in Java code

Placing them on local variables in an interface is just plain silly.

12 Responses to val vs final

  1. Mathias says:

    This often happens in my projects when I refactor with Eclipse. It has a setting to make variables final, which I checked once and then never unchecked.

    From a programming language point of view, I think having to mark mutable variables explicitly would have been better, but I don’t feel like the added, perhaps unnecessary final modifiers that Eclipse introduces distract me in any way. Perhaps there’s no added value, but there’s no harm either.

    • pveentjer says:

      I made the connection to eclipse already 🙂

      Personally I find the option just as useless as the ‘this.’ addition. More code to read without providing value to me. We have been in the _ and m_ prefix area but most ide’s show a clear distinction on the type of variable (local vs normal field vs static field) based on colors.

      • henrikb says:

        I have actually started experimenting with final on local variables since I actually think they “provide value” both to myself and other readers of the code.

        The value they provide is “readability” and clarity; by declaring something final you tell the reader of the code (a human, not the compiler) that your intention with this variable is that it should not be changed.

      • pveentjer says:

        He Hendrik,

        I think it is really a matter of taste/style. But from personal experience, if I look at the influence final access modifier on local variables has on reducing the number of bugs, I find the added value limited.

        I have no problem with it if the syntax clutter (e.g. in Scala) is low, but in Java it is a bit more verbose. I can live with it if people want to use final.. and I can just as easily live with it if they don’t want to do it.

  2. Jed Wesley-Smith says:

    I have my auto-formatter set to put final on _everything_ it possibly can. If something isn’t final it is because it is being re-assigned to.

    I probably wouldn’t be so hard-arsed about it if I was working exclusively on my own code, but I have to deal with a lot of code that is either old or written by a broad array of engineers, so tracking down assignment and side-effects can be a significant part of the effort in understanding it.

    If someone modifies code where every reference is final and removes the final keyword, it is usually pretty obvious that they are doing something wrong. Without final, it can be less obvious.

    So, it isn’t necessarily just about you, but about the general maintainability of the code. If you work on your own you may not care, but if you share your code base this can be a significant problem.

    Oh, and val isn’t final, it can still be overridden, you need final for that.

    • pveentjer says:

      Perhaps everyone his thing, but adding final to all local variables is not making my day any better. I can imagine that if you have complex methods (longer than 15 lines) it can be useful, but it feels like overkill for most mehods I touch. And I currently manage code that has been written by multiple teams over multple years and contains a lot of multi threading and other difficult stuff.

      Now on the more interesting side.
      I don’t think (not certain) that for local variables (so variables declared inside a method body) it has any effect from a bytecode perspective it something is val or not.
      You are partially right with the val vs final val on fields. The field itself is final in both cases on bytecode level, so there it makes no difference. But the final does has an effect on the generated getter since with final, the getter also is final and without the getter is not.

    • Dimitar says:

      You might consider using IntelliJ IDEA – it has a different syntax highlighter color for reassigned and once-assigned variables. I’ve set reassigned variables to maroon (dark red) and it works great.

  3. Andrew Phillips says:

    I see this as one of many example of “IDE habituation” problems, albeit one with a nice Scala/Java twist (surprise, surprise, Peter ;-)).

    It’s surprising how often programmers seem to think everyone is using the same IDE with the same settings. Even in quite small project teams where there are supposedly “shared” settings, code that looks fine in one team member’s IDE can be littered with warnings on the next screen.

    As we can see from this and other posts, these kind of things can actually have a significant impact on productivity, even if it’s only time taking by one developer “cleaning up” warnings left by another’s IDE. I’d be curious to know what, if any, research has been done on this issue.

    For what it’s worth, my preference in this particular case is *not* to use final on method parameters except where necessary (e.g. referenced in inner classes). Like Peter, I find the method declarations more readable, although admittedly that’s not a great argument because one can quite easily learn to “tune out” syntax elements with practice.

    In order to catch weird uses of method parameters, I have Eclipse’s “warn on parameter reassignment” option on.

  4. Rino says:

    Same goes for creating a public class. Most IDE’s create a class with public acces where package access might be sufficient (and ensures the package encapsulation. Why would you make all of your classes public?

    In many cases the problem could be solved by creating a project stylesheet that all teammembers use and is maintained by the project lead or architect.

  5. Andriy Palamarchuk says:

    I used to specify “final” on method parameters. At some point I started to rely on Checkstyle. It has a check for parameters assignment. This way I get clean code *and* enforce the convention. The bonus is that Checkstyle will find parameter assignment introduced by anybody on the team.

  6. Petro says:

    There’s an old thread on stackoverflow about why in java classes written by Doug Lea there’s copying into final local variable:

    Though case above is different from yours I think that compiler could produce different bytecode depends on whenever final present or not. The best way to find out is to compile class and do bytecode diff. I can’t read bytecode so I can’t try that for myself but for somebody who can it should be relatively easy to find out a difference.

  7. Peter Lawrey says:

    A class might be too long (or become too long) to easily determine if a field is effectively final. If you have a method which is too long then you should break up the method. Feeling the need to add final to local variables might be an indication of a bigger problem. 😉

Leave a Reply to pveentjer Cancel reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: