| 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 |