Using final variable in lambda with construction initialization

Mayank Garg
1 min readJan 24, 2021

Final variable must be initialized either when defining them, or in the contractor. But initializing them in constructor came with a surprising twist, they can’t be used in lamda methods. They can be used in internal class.

I don’t know the reason, but i am getting a complier error in mRunnable1. The error is the final variable mInput has not been initialized.

class TestClass {

private final int mInput;

TestClass(){
mInput = 1;
mRunnable1.run();
mRunnable2.run();
}

private Runnable mRunnable1 = () -> {
System.out.println("Executing runnable " + mInput);
};
private Runnable mRunnable2 = new Runnable() {
@Override
public void run(){
System.out.println("Executing runnable " + mInput);
}
};
}

My suspicion is that it is related to how Java lambda are initialized and stored. It looks like lamba expression is like object, but they are stateless , some details are here..

The variable should final or effectively final.

If we remove the final from mInput then, there is no issue with the code.

class TestClass {

private int mInput;

TestClass(){
mInput = 1;
mRunnable1.run();
mRunnable2.run();
}

private Runnable mRunnable1 = () -> {
System.out.println("Executing runnable " + mInput);
};
private Runnable mRunnable2 = new Runnable() {
@Override
public void run(){
System.out.println("Executing runnable " + mInput);
}
};
}

I guess it tries to capture the final variable when the lambda is declared, as it is not initialized at the time of declaration, it is not able to capture the variable.

--

--