Where variables of out scope is stored for lambda expressions

java, java-8, lambda, memory

Solution

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.

Problem

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 ?

Original source

Related problems