Reputation: 3215
I've read that the external variables which a lambda expression uses must be final or effectively final. If I try to modify an external String value in the body of a Supplier, for instance, the compiler blocks me, as by the definition above. But if I use an external Pojo (modifying its attribute - so its internal state), then it works correctly and negate the declaration above.
How comes?
package com.quicktutorialz.test;
import java.util.function.Supplier;
public class MainApplication {
public static void main(String[] args){
// MY NON-EFFECTIVELY-FINAL POJO
NamePojo namePojo = new NamePojo();
namePojo.setName("Luisa");
//MY LAMBDA
Supplier<String> supplier = () -> {
namePojo.setName("Alex"); //HOW IS THAT POSSIBLE?!?!
return "Hello " + namePojo.getName();
};
System.out.println(supplier.get());
}
}
class NamePojo {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Upvotes: 1
Views: 87
Reputation: 35427
You're mixing a final variable and an immutable one.
A final variable means that it cannot be reassigned. Example:
void doSomething() {
int a = 0; // is effectively final
int b = 1; // is not effectively final
b = 2;
}
An immutable variable means that its external representation won't change. This mostly means that its fields are final
or effectively final. Example:
class A {
int value;
A(int value) { this.value = value; }
int getValue() { return this.value; }
}
public void doSomething() {
A a = new A(0);
// no way to change a.value
}
public class MainApplication {
public static void main(String[] args){
// MY NON-EFFECTIVELY-FINAL POJO
NamePojo namePojo = new NamePojo(); // namePojo is assigned.
namePojo.setName("Luisa"); // namePojo is changed, but not reassigned.
//MY LAMBDA
Supplier<String> supplier = () -> {
// namePojo is changed, but not reassigned.
namePojo.setName("Alex"); //HOW IS THAT POSSIBLE?!?!
return "Hello " + namePojo.getName();
};
System.out.println(supplier.get());
}
}
The content of your variable namePojo
is changed, but the variable itself is never reassigned, since it's not reassigned, it's effectively final. The reference to namePojo
never changed in your code, making it effectively final.
Upvotes: 4