benf.org : other : cfr : Java 8 Lambdas |
The lambda functionality in java 8 is very well documented - I found the following to be more than enough!
Brian Goetz's excellent article on lambda translation design for java 8.As of 0_11 CFR is able to decompile lambda expressions... as of 0_27, post beta103 lambdas.
please note - when desugaring lambdas, CFR relies on your JRE, i.e. if you're trying to desugar a call to Consumer::andThen, and you've got Java 7 - CFR will not be able to desugar it!
What's particularly interesting (to me!) is that before I dug into this, I was expecting lambdas to simply be yet more syntactic sugar around anonymous inner classes - indeed Idea 12 'hides' anonymous inners behind lambda syntax, which is quite funny...
public class LambdaTest2 { Integer invoker(int arg, UnaryFunction<Integer, Integer> fn) { return fn.invoke(arg); } public int test(int y) { return invoker(3, x -> x + y + 1); } }
There are a couple of things of interest here, which mean that un-desugared, we can't treat this as real java:
public class LambdaTest2 { public LambdaTest2(){ } Integer invoker(int arg, UnaryFunction<Integer, Integer> fn){ return fn.invoke(Integer.valueOf(arg)); } public int test(int y){ return this.invoker(3, (UnaryFunction)LambdaMetafactory.metaFactory(null, null, null, invoke(X ), lambda$2(int Integer ), ConstantUTF8[(Ljava/lang/Integer;)Ljava/lang/Integer;])(y)).intValue(); } private static /* synthetic */ Integer lambda$2(int v0, Integer v1){ return Integer.valueOf((v1.intValue() + v0 + 1)); } }
As of 0_11, I haven't figured out if it's possible to determine the names which were given to the lambda arguments, so I'm making up names for them...
public class LambdaTest2 { public LambdaTest2(){ } Integer invoker(int arg, UnaryFunction<Integer, Integer> fn){ return fn.invoke(Integer.valueOf(arg)); } public int test(int y){ return this.invoker(3, arg_0 -> Integer.valueOf((arg_0.intValue() + y + 1))).intValue(); } }
public class org.benf.cfr.tests.LambdaTest2 { public org.benf.cfr.tests.LambdaTest2(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return java.lang.Integer invoker(int, org.benf.cfr.reader.util.functors.UnaryFunction); Code: 0: aload_2 1: iload_1 2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 5: invokeinterface #3, 2 // InterfaceMethod org/benf/cfr/reader/util/functors/UnaryFunction.invoke:(Ljava/lang/Object;)Ljava/lang/Object; 10: checkcast #4 // class java/lang/Integer 13: areturn public int test(int); Code: 0: aload_0 1: iconst_3 2: iload_1 3: invokedynamic #5, 0 // InvokeDynamic #0:lambda$:(I)Lorg/benf/cfr/reader/util/functors/UnaryFunction; 8: invokevirtual #6 // Method invoker:(ILorg/benf/cfr/reader/util/functors/UnaryFunction;)Ljava/lang/Integer; 11: invokevirtual #7 // Method java/lang/Integer.intValue:()I 14: ireturn private static java.lang.Integer lambda$2(int, java.lang.Integer); Code: 0: aload_1 1: invokevirtual #7 // Method java/lang/Integer.intValue:()I 4: iload_0 5: iadd 6: iconst_1 7: iadd 8: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 11: areturn }
Last updated 08/2013 |