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);
        });
    }
}