Lambda behaving differently than anonymous inner class
    Ivan Babanin 
    babanin at gmail.com
       
    Wed Mar 26 21:22:18 UTC 2014
    
    
  
It's definitely a javac bug.
Anonymous class and lambda converts to following intermediate
representations:
@Override()
public Integer get(Integer t) {
    return (let /*synthetic*/ final Integer $112619572 = t in 
       (let /*synthetic*/ final Integer $1295226194 = t =
Integer.valueOf((int)(t.intValue() + 1)) in $112619572));
}
/*synthetic*/ private static Integer lambda$main$0(final Integer t) {
    return (let /*synthetic*/ final Integer $1146147158 = t =
Integer.valueOf((int)(t.intValue() + 1)) in t);
}
In lambda generated method parameter marked as final, because LambdaToMethod
translator 
marks all parameters as FINAL (according source code
LambdaTranslationContext.translate(.) : 1899).
Then let expression builder checks variable flags and when if it's final
omits temporary variable generation
(according source code Lower. abstractRval(.) : 2277), because modification
considered to be prohibited.
Possible solutions:
1) Forbid parameter modification inside lambda or
2) Remove FINAL flag from local variable
(LambdaTranslationContext.translate(.) : 1894)
   and parameter (LambdaTranslationContext.translate(.) : 1899) in lamda
generated method:
 
     case LOCAL_VAR:
       ret = new VarSymbol(FINAL, name, types.erasure(sym.type),
translatedSym);
     ...
     
     case PARAM:
       ret = new VarSymbol(FINAL | PARAMETER, name, types.erasure(sym.type),
translatedSym);
     ...
I removed FINAL flag and got expected results on tests from:
https://bugs.openjdk.java.net/browse/JDK-8038420
sy,
Ivan
    
    
More information about the lambda-dev
mailing list