Protected variable access inside Lambda blocks
Mark Mahieu
markmahieu at gmail.com
Sat Nov 13 19:15:17 PST 2010
Hmm, actually I think there might be a slight wrinkle to watch out for in the current code - if my understanding is correct, then this example should print the result of calling toString() on the instance of 'Lexical':
class Lexical {
Lexical() {
Runnable r = #{
System.out.println(toString());
};
r.run();
}
public static void main(String[] args) {
new Lexical();
}
}
However, it's calling the Runnable's toString() instead (note the $1):
$ java Lexical
Lexical$1 at 3a3ee284
Many other cases do seem to work as I'd expect though, as will the above example if Lexical is made to override toString().
There's also an issue with 'this'...
class NoSuchField {
NoSuchField() {
Runnable r = #{ Object o = this; };
r.run();
}
public static void main(String[] args) {
new NoSuchField();
}
}
... which compiles but throws a NoSuchFieldError when run:
$ java NoSuchField
Exception in thread "main" java.lang.NoSuchFieldError: this
at NoSuchField$1.run(NoSuchField.java:4)
at NoSuchField.<init>(NoSuchField.java:5)
at NoSuchField.main(NoSuchField.java:9)
Finally, calling getClass() in a lambda expression causes an AssertionError at compile time:
class GetClass {
Runnable r = #{ getClass(); };
}
$ javac GetClass.java
...
java.lang.AssertionError
at com.sun.tools.javac.code.Types.rank(Types.java:2974)
at com.sun.tools.javac.code.Types.rank(Types.java:2946)
at com.sun.tools.javac.code.Symbol$TypeSymbol.precedes(Symbol.java:574)
at com.sun.tools.javac.code.Types.union(Types.java:3108)
at com.sun.tools.javac.code.Types.glb(Types.java:3370)
at com.sun.tools.javac.code.Types.capture(Types.java:3620)
at com.sun.tools.javac.comp.Attr.capture(Attr.java:3812)
at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1565)
at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1344)
...
Mark
On 14 Nov 2010, at 00:17, Arul Dhesiaseelan wrote:
> Thanks Mark and Peter for the clarification.
>
> -Arul
>
> On Sat, Nov 13, 2010 at 1:30 PM, Peter Levart <peter.levart at gmail.com> wrote:
> On Saturday, November 13, 2010 08:28:15 pm Arul Dhesiaseelan wrote:
> > Hi,
> >
> > I am trying to access a protected final defined in my SAM type from within
> > a Lambda block, but it fails with "cannot find symbol" compile error with
> > the prototype.
> >
> > Here is a simple test:
> >
> > public class ProtectedAccess {
> > public static abstract class LambdaAccess<T> {
> > protected static final String DEFAULT = "DEFAULT";
> > public abstract T block();
> > }
> >
> > public static void main(String... args) throws Exception {
> > LambdaAccess<String> lambdaAccess = #{
> > return DEFAULT;//compile error: unable to access this protected
> > constant
> > };
> > lambdaAccess.block();
> >
> > LambdaAccess<String> anonymousAccess = new LambdaAccess<String>() {
> > public String block () {
> > return DEFAULT;//works just fine in case of anonymous types
> > }
> > };
> > anonymousAccess.block();
> > }
> >
> > }
> >
> > I am not sure if this is a limitation or if I am doing something wrong
> > here.
> >
> > -Arul
>
> As of 15.10.2010, the lambdas are lexically scoped (see:
> http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html). In other words, code inside
> lambda sees only the symbols as the code immediately outside the lambda expression.
>
> Peter
>
>
>
>
More information about the lambda-dev
mailing list