Java Reference
In-Depth Information
Example 2-5. A final local variable being captured by an anonymous inner class
final
final String name = getUserName ();
button . addActionListener ( new
new ActionListener () {
public
public void
void actionPerformed ( ActionEvent event ) {
System . out . println ( "hi " + name );
}
});
This restriction is relaxed a bit in Java 8. It's possible to refer to variables that aren't final ;
however, they still have to be effectively final . Although you haven't declared the vari-
able(s) as final , you still cannot use them as nonfinal variable(s) if they are to be used in
lambda expressions. If you do use them as nonfinal variables, then the compiler will show an
error.
The implication of being effectively final is that you can assign to the variable only once.
Another way to understand this distinction is that lambda expressions capture values , not
variables. In Example 2-6 , name is an effectively final variable.
Example 2-6. An effectively final variable being captured by an anonymous inner class
String name = getUserName ();
button . addActionListener ( event -> System . out . println ( "hi " + name ));
I often find it easier to read code like this when the final is left out, because it can be just
line noise. Of course, there are situations where it can be easier to understand code with an
explicit final . Whether to use the effectively final feature comes down to personal choice.
If you assign to the variable multiple times and then try to use it in a lambda expression,
you'll get a compile error. For example, Example 2-7 will fail to compile with the error mes-
sage: local variables referenced from a lambda expression must be final or
effectively final .
Example 2-7. Fails to compile due to the use of a not effectively final variable
String name = getUserName ();
name = formatUserName ( name );
button . addActionListener ( event -> System . out . println ( "hi " + name ));
This behavior also helps explain one of the reasons some people refer to lambda expressions
as “closures.” The variables that aren't assigned to are closed over the surrounding state in
order to bind them to a value. Among the chattering classes of the programming language
world, there has been much debate over whether Java really has closures, because you can
refer to only effectively final variables. To paraphrase Shakespeare: A closure by any other
Search WWH ::




Custom Search