Il semble que les expressions lambda Java puissent accéder à des variables locales qui sont ** pratiquement finales **. Le livre de référence disait: "Des variables qui ne changent pas même si elles ne sont pas qualifiées avec ** final **."
"Il ne vient pas avec ** final **, mais il n'a pas du tout changé depuis qu'il a été déclaré, donc c'est la même chose que ** final **!"
Dans ce cas, la variable locale «i» est pratiquement définitive,
LambdaStudy.java
public class LambdaStudy {
public static void main(String[] args) {
int i = 10;
Calculate c = x -> x + i;
System.out.println(c.calc(20));//30
}
}
interface Calculate {
public int calc(int x);
}
Dans ce cas, puisque la valeur de «i» a été modifiée par incrémentation, elle n'est pratiquement pas définitive et une erreur de compilation se produit.
LambdaStudy.java
public class LambdaStudy {
public static void main(String[] args) {
int i = 10;
i++;
Calculate c = x -> x + i;//Local variable i defined in an enclosing scope must be final or effectively final
System.out.println(c.calc(20));
}
}
interface Calculate {
public int calc(int x);
}
Il ne change pas même s'il s'agit d'un type de référence.
Dans ce cas, «sb» est dû au fait que «sb.append (« d »)» ne change que l'objet référencé de la variable «sb», pas la variable «sb» elle-même. Il devient pratiquement définitif et peut être exécuté.
LambdaStudy.java
public class LambdaStudy {
public static void main(String[] args) {
int i = 10;
StringBuilder sb = new StringBuilder("abc");
sb.append("d");
Calculate c = x -> {
System.out.println(sb.toString());//abcd
return x + i;
};
System.out.println(c.calc(20));//30
}
}
interface Calculate {
public int calc(int x);
}
Si vous réaffectez à sb
, la destination de référence de sb
changera, donc elle ne sera pas pratiquement définitive. (Erreur de compilation)
LambdaStudy.java
public class LambdaStudy {
public static void main(String[] args) {
int i = 10;
StringBuilder sb = new StringBuilder("abc");
sb.append("d");
sb = new StringBuilder("efg");
Calculate c = x -> {
System.out.println(sb.toString());//Local variable sb defined in an enclosing scope must be final or effectively final
return x + i;
};
System.out.println(c.calc(20));
}
}
interface Calculate {
public int calc(int x);
}
Les variables essentiellement finales sont ** "des variables qui n'ont pas du tout changé depuis que la variable a été déclarée" **.
Recommended Posts