34

Possible Duplicate:
When should one use final?

I tend to declare all variables final unless necessary. I consider this to be a good practice because it allows the compiler to check that the identifier is used as I expect (e.g. it is not mutated). On the other hand it clutters up the code, and perhaps this is not "the Java way".

I am wondering if there is a generally accepted best practice regarding the non-required use of final variables, and if there are other tradeoffs or aspects to this discussion that should be made aware of.

Community
  • 1
  • 1
Landon Kuhn
  • 76,451
  • 45
  • 104
  • 130
  • 3
    The idea of optional code that may or may not express developer intent and that may or may not lead to compiler optimizations sounds like something out of an XKCD comic. – jordanpg Aug 14 '15 at 22:48
  • Big thing is to be very careful with what you mean by final. final mutable objects can still be modified, which some newbies forget. This is the big problem I have with final really, any time I'm working with a mutable object the *intent* of final gets muddy, I know the literal meaning, but does the person using final really okay with me modifying the object's contents even though it's final or not? – dsollen Jun 17 '16 at 19:42

8 Answers8

15

The "Java way" is inherently, intrinsically cluttery.

I say it's a good practice, but not one I follow.

Tests generally ensure I'm doing what I intend, and it's too cluttery for my aesthetics.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • 1
    This recaps exactly how I feel about it. I only use final in my static strings. Since Java passes the objects by value (unlike C ) the use of final in there is also only cluttering stuff up. In the end, you either know what you're doing or you don't. I have NEVER had a bug which could have been prevented by the use of final... Never! – Lawrence Jul 23 '13 at 14:13
15

Some projects routinely apply final to all effectively final local variables. I personally find reading such code much easier, due to the lessened cognitive load. A non-final variable could be reassigned anywhere, and it's especially problematic in code with multiple levels of nested ifs and fors. You never know what code path may have reassigned it.

As for the concern of code clutter, when applied to local variables I don't find it damaging—in fact it makes me spot all declarations more easily due to syntax coloring.

Unfortunately, when final is used on parameters, catch blocks, enhanced-for loops and all other places except local variables in the narrow sense, the code does tend to become cluttered. This is quite unfortunate because a reassignment in these cases is even more confusing and they should really have been final by default.

There are code linting tools that will flag the reassignment of these variables, and that helps.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
13

I consider it good practice, more for maintenance programmers (including me!) than for the compiler. It's easier to think about a method if I don't need to worry about which variables might be changing inside it.

Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
  • Yes! That's a really good point. Readability is enhanced because you instantly know that this variable is not going to be changed. It makes it simpler to think about. – Landon Kuhn May 21 '12 at 18:24
  • I would clarify this slightly, mostly for java newbies who may misread this. My first lazy read had me think you were saying it was easier to use an existing method because you didn't have to worry about the method changing anything, which made no sense as finial doesn't protect against that. On re-read I'm pretty sure you mean that when your reading an existing method and figuring out what it does it's easier to parse with a final assigned to it, which makes more sense. However, I'd be afraid newbie java folks may read it the way I original did and be too new to realize that doesn't work. – dsollen Jun 17 '16 at 19:45
  • 2
    One knows that a variable is not going to be re-assigned, but it could still very well be mutable! A final reference does not guarantee an immutable value, so it is debatable how much it helps in letting you know if a variable value will change. `AtomicReference` and `List` are good examples, while the references might be final, the contents can certainly change. – LaFayette Jan 10 '21 at 21:17
4

Yes, it's a very good idea, because it clearly shows what fields must be provided at object construction.

I strongly disagree that it creates "code clutter"; it's a good and powerful aspect of the language.

As a design principle, you should make your classes immutable (all final fields) if you can, because they may be safely published (ie freely passed around without fear they will be corrupted). Although note that the fields themselves need to be immutable objects too.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
3

It definitely gives you a better code, easy to see which all variables are going to be changed.

It also informs the compiler that it is not going to change which can result to better optimization.

Along side it allows your IDE to give you compile time notification if you tend to do any mistake.

mprabhat
  • 20,107
  • 7
  • 46
  • 63
  • 1
    I disagree. You may declare a collection as final but still you'll be able to change it's contents... The only thing you won't be able to do is assign another REFERENCE! I agree to use final for fields when needed but for local method variables??? Their scope should be limitative enough... That's just my opinion.. – Lawrence Jul 23 '13 at 14:16
2

Some good analysis tools, like PMD, advices to put always final unless necessary. So the convention in that tools says it's a good practice

But I think that so many final tokens in code may get it less human-friendly.

richarbernal
  • 1,063
  • 2
  • 14
  • 32
1

I would say yes, not so much for the compiler optimisation, but rather for readibility.

But personally I don't use it. Java is quite verbose by itself, and if we followed everything considered "good practice", the code would be unredable from all the boilerplate. It's a matter of preference, though.

Jakub Zaverka
  • 8,816
  • 3
  • 32
  • 48
0

You pretty much summed up the pros and cons...

I can just add another con:

the reader of the code need not to reason at all about the value of a final variable (except for rare bad-code cases).

So, yes, it's a good practice.

And the clutter isn't that bad, after you get used to it (like unix :-P). Plus, typical IDEs do it automatically for ya...

yair
  • 8,945
  • 4
  • 31
  • 50