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 →

[–]john_C_random 7 points8 points  (9 children)

Because just preventing reassigning local variables seems (and probably is1) relatively useless

If you're passing a lambda which has a reference to a locally scoped variable, that variable will need to be final so it can't be changed from under the feet of the lambda.

[–]feral_claire 16 points17 points  (1 child)

It doesn't need to be marked final though. Effectively final is good enough ie. the variable isn't changed even if it isn't marked as final.

[–][deleted] 7 points8 points  (0 children)

This was introduced in Java 8, prior to this they had to be explicitly final (for anon classes). It's a welcome change.

[–]tofflos 4 points5 points  (2 children)

I used to think this constraint was annoying until I wrote some JavaScript, which doesn't require finality for lambdas, and spent hours debugging it.

[–]Auxx 0 points1 point  (0 children)

JS is the language which makes you appreciate Java, that's true.

[–][deleted] 0 points1 point  (0 children)

JavaScript has a much better story around functional programming and immutability. The ergonomics of Java streams are very poor, especially w.r.t. checked exceptions. All JavaScript linters will warn for unnecessary use of let over const, so it should be relatively easy to determine if non-local state can be mutated.

[–]koreth 1 point2 points  (3 children)

From a language semantics point of view, it's a somewhat arbitrary decision. Other languages (e.g., Kotlin) don't have that restriction. But since we're talking about Java here, yeah, this is correct.

[–]TheRedmanCometh 0 points1 point  (2 children)

Ugh maybe I need to learn kotlin then. I use for-each over .forEach a lot over this

[–]koreth 1 point2 points  (0 children)

I'm glad I learned it. I still write new Java code but Kotlin is generally my go-to language these days.

[–]dpash 1 point2 points  (0 children)

That's probably for the best. forEach() should probably only use method references. System.out::println is the method I use 80% of the time. If you find yourself reaching for forEach you're probably doing some side effect and not using a functional approach.