-2

While going through the lambda expressions, I came across the below behavior for anonymous inner classes and lambda expressions. What could be the reason behind this?

Human h = new Human() {
int a = 2;
@Override
public void sing() {

System.out.println(++a);
}

};

h.sing();
h.sing();

O/P

3
4

Whereas for lambdas I get below:

Human h = () -> {

int a = 2;
System.out.println(++a);
};

h.sing();
h.sing();

}

O/P

3
3
Andronicus
  • 25,419
  • 17
  • 47
  • 88
ghostrider
  • 2,046
  • 3
  • 23
  • 46
  • 6
    The one in the anonymous class isn't a local variable, it's a field that stays alive as long as the object does. The one in the lambda is a local variable that only lives inside the method and isn't saved between calls. – user Apr 25 '20 at 18:16
  • See https://stackoverflow.com/questions/48401216/can-java-lambdas-have-state/48401440 – Sotirios Delimanolis Apr 25 '20 at 18:29

2 Answers2

6

Those are not equivalent. The first function modifies a variable outside of it's scope, whereas in the second example each time you're invoking h.sing();, the body of that function is being invoked. That means, a variable is instantiated with value 2 every time.

Andronicus
  • 25,419
  • 17
  • 47
  • 88
5

Your lambda is more or less equivalent to:

Human h = new Human() {
    @Override
    public void sing() {
        int a = 2;    
        System.out.println(++a);
    }
};
h.sing();
h.sing();

There is no way to declare a lambda with directly mutable state.

Johannes Kuhn
  • 14,778
  • 4
  • 49
  • 73