Es scheint, dass Java-Lambda-Ausdrücke auf lokale Variablen zugreifen können, die ** praktisch endgültig ** sind. Das Nachschlagewerk sagte: "Variablen, die sich nicht ändern, auch wenn sie nicht mit ** final ** qualifiziert sind."
"Es kommt nicht mit ** final **, aber es hat sich seit seiner Erklärung überhaupt nicht geändert, also ist es dasselbe wie ** final **!"
In diesem Fall ist die lokale Variable "i" praktisch endgültig.
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);
}
In diesem Fall ist der Wert von "i", da er durch Inkrementieren geändert wurde, praktisch nicht endgültig und es tritt ein Kompilierungsfehler auf.
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);
}
Es ändert sich auch dann nicht, wenn es sich um einen Referenztyp handelt.
In diesem Fall liegt "sb" daran, dass "sb.append (" d ")" nur das referenzierte Objekt der Variablen "sb" ändert, nicht die Variable "sb" selbst. Es wird praktisch endgültig und kann ausgeführt werden.
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);
}
Wenn Sie sb
neu zuweisen, ändert sich das Referenzziel von sb
, sodass es praktisch nicht endgültig ist. (Kompilierungsfehler)
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);
}
Im Wesentlichen endgültige Variablen sind ** "Variablen, die sich seit der Deklaration der Variablen überhaupt nicht geändert haben" **.
Recommended Posts