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;
}
}
The variable is (effectively) final, its fields are not.
You're mixing a final variable and an immutable one.
A final variable means that it cannot be reassigned. Example:
An immutable variable means that its external representation won't change. This mostly means that its fields are
finalor effectively final. Example:In your case:
The content of your variable
namePojois changed, but the variable itself is never reassigned, since it's not reassigned, it's effectively final. The reference tonamePojonever changed in your code, making it effectively final.