Translating lambda expressions as Synthetic non-static methods: Capturing states for lambdas appears in Local or Anonymous inner classes

Ali Ebrahimi ali.ebrahimi1781 at gmail.com
Sat Jun 25 04:10:56 PDT 2011


Hi all,
scenario 3: Capturing states for lambdas appears in Local or Anonymous inner
classes

In this case lambda expressions translated as Synthetic non-static methods
in Local or Anonymous inner classes.

Translating lambda expressions as Synthetic non-static methods: Capturing
states for lambdas located in Local or Anonymous inner classes

public class CapturingInLocalAndAnonymousClassLambdas {

    int x=10;
    public void test(){
    }

    class Inner{
        int y=100;
        public void foo(){
             final int z=1000;

             class Local{
                 int w=10000;

                 public void bar(){
                     call(#{s ->
                             x++;
                             y--;
                             w++;
                             System.out.println(s+":"+(x+y+z+w));
                             test();
                     });

                     new Runnable(){
                         int count=0;

                         @Override
                         public void run() {
                            call(#{s ->
                             x++;
                             y--;
                             w++;
                             count++;
                             System.out.println(s+":"+(x+y+z+w+count));
                             test();
                        });

                         }
                     }.run();
                 }

                 public void call(Block<String> block){
                     block.call("test");
                 }
             }
            new Local().bar();
        }
    }
}

Translated as:

strategy 1: capturing all outer scops

public class CapturingInLocalAndAnonymousClassLambdas {

    int x=10;
    public void test(){
    }

    static MethodHandle local$lambda$1mh=null;
    static MethodHandle anony$local$lambda$1mh=null;

    class Inner{
        int y=100;
        public void foo(){
             final int z=1000;

             class Local{
                 int w=10000;

                 {
                 if(local$lambda$1mh == null)
                    local$lambda$1mh =
LambdaHelper.createVirtualMH(Local.class, "local$lambda$1",
MethodType.methodType(void.class,
CapturingInLocalAndAnonymousClassLambdas.class, Inner.class,
Integer.class,String.class));
                 }

                 public void
local$lambda$1(CapturingInLocalAndAnonymousClassLambdas captureAllScopes,
Inner inner, Integer z, String s) {
                     captureAllScopes.x++;
                     inner.y--;
                     Local.this.w++;
                     System.out.println(s + ":" + (captureAllScopes.x +
inner.y + z + Local.this.w));
                     captureAllScopes.test();
                 }

                 public void bar(){
                     call(LambdaHelper.asSam(local$lambda$1mh, Block.class,
Local.this, CapturingInLocalAndAnonymousClassLambdas.this, Inner.this, z,
null));

                     new Runnable(){
                         int count=0;

                         {
                             if(anony$local$lambda$1mh==null)
                              anony$local$lambda$1mh =
LambdaHelper.createVirtualMH(this.getClass(), "anony$local$lambda$1",
MethodType.methodType(void.class,
CapturingInLocalAndAnonymousClassLambdas.class,Local.class, Inner.class,
Integer.class, String.class));

                         }

                         public void
anony$local$lambda$1(CapturingInLocalAndAnonymousClassLambdas
captureAllScopes,Local local, Inner inner, Integer z, String s) {
                             captureAllScopes.x++;
                             inner.y--;
                             local.w++;
                             this.count++;
                             System.out.println(s + ":" +
(captureAllScopes.x + inner.y + z + Local.this.w + count));
                             captureAllScopes.test();
                         }

                         @Override
                         public void run() {
                             call(LambdaHelper.asSam(anony$local$lambda$1mh,
Block.class, this, CapturingInLocalAndAnonymousClassLambdas.this,
Local.this, Inner.this, z, null));
                         }
                     }.run();
                 }

                 public void call(Block<String> block){
                     block.call("test");
                 }
             }
            new Local().bar();
        }
    }

}

strategy 2: without capturing outer scops: since generated method can access
outer scopes therefore we don't need capture them.

public class CapturingInLocalAndAnonymousClassLambdas {

    int x=10;
    public void test(){
    }

    static MethodHandle local$lambda$withoutCapturing$1mh=null;
    static MethodHandle anony$local$lambda$withoutCapturing$1mh=null;

    class Inner{
        int y=100;
        public void foo(){
             final int z=1000;

             class Local{
                 int w=10000;

                 {

                   if(local$lambda$withoutCapturing$1mh == null)
                    local$lambda$withoutCapturing$1mh =
LambdaHelper.createVirtualMH(Local.class, "local$lambda$1",
MethodType.methodType(void.class, Integer.class,String.class));
                 }

                 public void local$lambda$1(Integer z, String s) {
                     x++;
                     y--;
                     w++;
                     System.out.println(s + ":" + (x + y + z + w));
                     test();
                 }

                 public void bar(){


call(LambdaHelper.asSam(local$lambda$withoutCapturing$1mh, Block.class,
Local.this, z, null));

                     new Runnable(){
                         int count=0;

                         {


if(anony$local$lambda$withoutCapturing$1mh==null)
                              anony$local$lambda$withoutCapturing$1mh =
LambdaHelper.createVirtualMH(this.getClass(), "anony$local$lambda$1",
MethodType.methodType(void.class, Integer.class, String.class));

                         }

                         public void anony$local$lambda$1(Integer z, String
s) {
                             x++;
                             y--;
                             w++;
                             this.count++;
                             System.out.println(s + ":" + (x + y + z + w +
count));
                             test();
                         }

                         @Override
                         public void run() {


call(LambdaHelper.asSam(anony$local$lambda$withoutCapturing$1mh,
Block.class, this, z, null));
                         }
                     }.run();
                 }

                 public void call(Block<String> block){
                     block.call("test");
                 }
             }
            new Local().bar();
        }
    }
}


Best Regards,
Ali Ebrahimi


More information about the lambda-dev mailing list