We all agree that the first example won't work as local variables or parameters must be final or effectively final to be used within a lambda expression body.
But your second example does not involve local variables or parameters, as str
is an instance field. Lambda expressions can accessing instance fields the same way as instance methods:
15.27.2. Lambda Body
A lambda body is either a single expression or a block (§14.2). Like a method body, a lambda body describes code that will be executed whenever an invocation occurs.
In fact, the java compiler creates a private method lambda$0
out of your lambda expression, that simply accesses the instance field str
:
private java.lang.String lambda$0() {
0 aload_0; /* this */
1 getfield 14; /* .str */
4 areturn;
}
Another point of view: You could also implement the Supplier
using a plain-old anonymous inner class:
public Supplier<String> makeSupplier() {
return new Supplier<String>() {
public String get() { return str; }
};
}
Accessing instance fields from inner classes is very common and not a speciality of Java 8.