Card 07/ 09
All 9 cards
GotchaDifficulty: Advanced1 min
Why Your Lambda Cannot Change That Variable
A counter incremented inside a forEach. The compiler refuses the line, with a message about a variable being final when nothing in the source says final.
int total = 0;
invoices.forEach(invoice -> total += invoice.pence());Report.java:2: error: local variables referenced from a lambda expression must be final or effectively finalA lambda captures a copy of the local variables it uses, because the method that declared them may have returned long before the lambda runs. Allowing the lambda to assign to its copy would look like changing the original and would not be.
So the compiler insists that captured locals never change at all — declared final, or never assigned to after their first value, which is what "effectively final" means.
The real answer is that summing in a forEach is the wrong shape. Let the pipeline produce the value rather than accumulating into something outside it.
long total = invoices.stream().mapToLong(Invoice::pence).sum();