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
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