Why don't instance fields need to be final or effectively final to be used in lambda expressions?

28

I'm practicing lambda expressions in Java. I know local variables need to be final or effectively final according to the Oracle documentation for Java SE 16 Lambda Body :

Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be final or effectively final (§4.12.4), as specified in §6.5.6.1.

It doesn't say why though. Searching I found this similar question Why do variables in lambdas have to be final or effectively final?, where StackOverflow user "snr" responded with the next quote:

Local variables in Java have until now been immune to race conditions and visibility problems because they are accessible only to the thread executing the method in which they are declared. But a lambda can be passed from the thread that created it to a different thread, and that immunity would therefore be lost if the lambda, evaluated by the second thread, were given the ability to mutate local variables.

  • Source: Why the restriction on local variable capture?

This is what I understand: a method can only be executed by one thread (let's say thread_1) at a time. This ensures the local variables of that particular method are modified only by thread_1. On the other hand, a lambda can be passed to a different thread (thread_2), so... if thread_1 finishes with the lambda expression and keeps executing the rest of the method it could change the values of the local variables, and, at the same time, thread_2 could be changing the same variables within the lambda expression. Then, that's why this restriction exists (local variables need to be final or effectively final).

Sorry for the long explanation. Am I getting this right?

But the next questions would be:

  • Why isn't this case applicable to instance variables?
  • What could happen if thread_1 changes instance variables at the same time as thread_2 (even if they are not executing a lambda expression)?
  • Are instance variables protected in another way?

I don't have much experience with Java. Sorry if my questions have obvious answers.

Share
Improve this question
3
  • 2
    There are some good explanations with example here - baeldung.com/java-lambda-effectively-final-local-variables, not sure whether you have read it – aksappy Apr 12 at 20:32
  • 7
    "a method can only be executed by one thread (let's say thread_1) at a time" => nope, however the local variables are "initialised and separate" each time the method is executed. – assylias Apr 12 at 20:32
  • 2
    Local variables are handled differently to fields. A reference to a field is certain given a reference to its containing object. Not so with a local variable when its value changes. – Bohemian Apr 12 at 20:39

Comments

Popular posts from this blog

Meaning of `{}` for return expression

Get current scroll position of ScrollView in React Native

flutter websocket connection issue