Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where variables of out scope is stored for lambda expressions

As I know for inner and anonimous classes variables of outer scope is stored in generated bytecode (e.g. OuterClass$1.class). I would like to know where is stored variables of the next example:

public Function<Integer, Integer> curring(Integer elem) {
    return x -> x * elem;
}

Arrays.asList(1, 2, 3, 4, 5).stream().map(curring(2)).map(curring(5)).forEach(System.out::println);

Lambda is translated to methods, not classes. Does it mean that for this 2 calls would be generated 2 separate methods ?

like image 941
Ving Avatar asked Dec 23 '22 18:12

Ving


1 Answers

This expression x -> x * elem; is going to be de-sugared to a static method, that looks like this:

  private static Integer lambda$curring$0(int x, int y){
      return x*y;
  }

Because you are capturing the elem variable inside the lambda, the lambda is said to be a stateful lambda.

On the other hand, your map operation needs an actual instance of java.util.Function - and that is generated at runtime that will kind of look like this:

 final class Test2$$Lambda$1 implements java.util.function.Function {
      private final Integer arg$1;

      private Test2$$Lambda$1(Integer arg$1){
          this.arg$1 = arg$1;
      }

      // static factory method
      private static java.util.function.Function get$Lambda(Integer i){
            return new Test2$$Lambda$1(i); // instance of self
      }

       public Integer apply(Integer x) {
          return YourClass.lambda$curring$0(this.arg$1, x);    
       }
 }

Before Function.apply (inside your map operation) is called a new instance of Test2$$Lambda$1 is generated via the static factory method get$Lambda. This is needed "carry" the elem variable.

Because of that every time map gets called a new instance is created.

Since your Stream has five initial elements, there will be 10 instances created - for the two map operations.

But generally this is an implementation detail that might easily change one day - so don't rely on it. Also the creation and collection (by garbage collector) of this short lived instances are quite cheap and it will not impact your app almost at all.

like image 79
Eugene Avatar answered Jan 03 '23 10:01

Eugene