I can't understand why the implementers of the java language made it so that the variable used in a lambda and passed there from a function scope has to be final.
I decompiled this code:
public class Main {
@FunctionalInterface
interface Test {
void method(int t);
}
static void test(Test t) {
t.method(3);
}
public static void main(String... args) {
int a = 3;
test((i)-> {
System.out.println(a + i);
});
}
}
and what the compiler does is copy that variable as if it was passed through a constructor. I got these 3 classes:
1:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import Main.1;
import Main.Test;
public class Main {
public Main() {
}
static void test(Test var0) {
var0.method(3);
}
public static void main(String... var0) {
byte var1 = 3;
test(new 1(var1));
}
}
2:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import Main.Test;
final class Main$1 implements Test {
Main$1(int var1) {
this.val$a = var1;
}
public void method(int var1) {
System.out.println(this.val$a + var1);
}
}
3:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
@FunctionalInterface
interface Main$Test {
void method(int var1);
}
Why couldn't the implementers just copy the variable regardless of whether it was modified or not so we could do this:
public class Main {
@FunctionalInterface
interface Test {
void method(int t);
}
static void test(Test t) {
t.method(3);
}
public static void main(String... args) {
int a = 3;
test((i)-> {
a += 1; // allow modification, a is copied anyway, why not?
System.out.println(a + i);
});
}
}