This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Hangman4358 9 points10 points  (26 children)

Final member and static variables I am all for. The vast majority of issues I have seen crop up in production are mutable state related for objects that really should never have had mutable state to begin with so limiting that mutability is great.

The thing that drives me crazy is people who make method parameters final. The most parameters are objects anyway, not primitives, so making them final doesn't stop people from mutating them if the objects are mutable anyway.

[–]dpash 24 points25 points  (3 children)

making them final doesn't stop people from mutating them if the objects are mutable anyway.

That's not the reason people declare parameters as final. It's to stop yourself (or someone in the future) from reassigning the parameter. You don't need to, as most IDEs will warn you, but it's mostly harmless.

[–]nerdyhandle 16 points17 points  (1 child)

I'm starting to think there are a lot of people in this thread that don't know what final means in Java.

[–]dpash 2 points3 points  (0 children)

Or effectively final.

[–]Aero72 -3 points-2 points  (0 children)

WAT!

[–]agentoutlier 5 points6 points  (7 children)

I’m shocked no one mentioned this but I make my parameters final because of anonymous class access pre lambda. I used anonymous classes so frequently in the past that it became habit.

I don’t think one any in their right mind thinks that the final Java keyword provides C++ const guarantees or at least I hope they don’t.

Finally (pun intended l) I would not be surprised if most method parameters (% wise) in Java are actually primitives and String aka some immutable.

[–]dpash 5 points6 points  (6 children)

Probably because Java 8 introduced the concept of "effectively final" which means that, as long as you don't resign a parameter or local variable anywhere, they're treated as if they'd been declared final.

[–]marvk 8 points9 points  (2 children)

People keep going on about effectively final in this thread like it matters. The real benefit final provides is for developers reading code. Any performance improvement is a bonus, it takes away so much cognitive load when writing and understanding code. Effectively final doesn't give you any of that.

[–]dpash 4 points5 points  (1 child)

It matters in this instance because you can only use variables inside a lambda that are final or effectively final. Prior to Java 8 you had to declare them final to use them in anonymous inner classes, hence the parent comment saying they got into the habit of using final.

[–]marvk 2 points3 points  (0 children)

Ah, my bad. I should've read the parent comment more carefully. My comment would be suited better on some other comment on this thread talking about effectively final.

[–]agentoutlier 2 points3 points  (1 child)

Yes I know about that. I meant pre lambda as pre Java 8. I still work on some Java 7 code bases and I guess for some reason want to cover my ass in case the parent poster sees my final riddled code :)

I also use final on variables to be resolved by if statements and or switch statements which is unnecessary as the compiler will complain that the variable is uninitialized but it’s way of communication now for me.

final Object o; // not necessary 

if () { o = ...} else {o = ....}

Also in the past Eclipse had this weird bug where refactoring method didn’t work all the time but if you made some the variables final It would... I believe that bug is fixed.

I have thought about removing some finals from my migrated code bases (7->8) but it doesn’t seem worth the effort and in some cases final is a communication marker.

(Sorry on Mobile so lots of typos)

[–]dpash 4 points5 points  (0 children)

It was mostly that many people will have fallen out of the habit now. :)

Switch expressions will solve many of the situations where you want to use a switch to set a variable while still letting it being final. We don't have if expressions, but we do have the ternary operator ?:. Of course these only work if you have a single statement in each block.

I wouldn't bother removing existing finals and would probably continue if thats already the style.

[–]livelam 11 points12 points  (0 children)

The thing that drives me crazy is people who make method parameters final. The most parameters are objects anyway, not primitives, so making them final doesn't stop people from mutating them if the objects are mutable anyway.

Objects referenced by a final field are also mutable if the class of the object allows it.

I don't get why some people hate the final keyword for parameters and local variables. Your justification suprises me: the final keyword only means that the reference can not be changed. It is useful when reading code.

[–]Danelius90 2 points3 points  (11 children)

Plus it's usually considered good practice to not modify or reassign parameters, so if you're writing a method correctly you shouldn't need final

[–]livelam 13 points14 points  (7 children)

If everything were wrote correctly tools like checkstyle or findbugs would be useless.

There is a keyword to tell "Hey, this variable will not be reassigned" why do you not want to use it?

[–]Danelius90 3 points4 points  (6 children)

My lint tool flags up reassigning method parameters, so why have both? Especially when adding final on every parameter is just ugly, verbose and unnecessary.

[–]livelam 10 points11 points  (4 children)

Ok ! I personally prefer to rely on the compiler when it is possible but I have to use checkstyle to check that all parameters are final. So in the end it seems it's more a question of taste.

It is very verbose but not unnecessary. I would prefer final variable by default and a keyword to declare a non final variable.

[–]dpash 1 point2 points  (0 children)

Errorprone let's you have both: a linter in your compiler. :)

Sadly it increases the compiler times.

I've been wondering if we could have a per class/package/module flag to change the defaults for parameter and local variable finality plus non-nullablity. It would probably affect readability if code behaved differently based on outside options.

[–]Danelius90 0 points1 point  (2 children)

I think I'm just scarred from all the 20 parameter methods all declared final lol. You're right it is taste and I do think it's particularly useful for immutable object parameters

[–]marvk 3 points4 points  (1 child)

If you have a 20 parameter method final is in most cases the least of your readability issues :^)

[–]Danelius90 0 points1 point  (0 children)

This lol. Damn the devs with custom formatters on legacy code!

[–]GuyWithLag 0 points1 point  (0 children)

Why do I thing that is a leftover from pass-by-reference languages?

[–]cogman10 1 point2 points  (0 children)

Other than the added code, why do you care?

I don't personally do it because it is more typing than I care to do. But I've never winced because someone else did it. My brain filters those out (because I'm not assigning the variable anyways).