Allocation of Lambdas that capture "this"

Sam Pullara sam at sampullara.com
Tue Oct 14 19:40:57 UTC 2014


Since you can do this — even if wrong — with anonymous inner classes I
think it probably should be generally allowed.

Sam

final Runnable r = ()->{ (this).o.toString(); }; // javac error
final Object o; // assigned in constructor
{
  r.run();
}
public ZhongTest() {
  this.o = "";
}

java.lang.NullPointerException
	at spullara.ZhongTest.lambda$new$0(ZhongTest.java:10)
	at spullara.ZhongTest$$Lambda$1/693632176.run(Unknown Source)
	at spullara.ZhongTest.<init>(ZhongTest.java:13)


On Tue, Oct 14, 2014 at 11:36 AM, Zhong Yu <zhong.j.yu at gmail.com> wrote:

> On Mon, Oct 13, 2014 at 1:12 PM, Neal Gafter <neal at gafter.com> wrote:
> > On Wed, Aug 20, 2014 at 4:58 PM, Zhong Yu <zhong.j.yu at gmail.com> wrote:
> >>
> >> Is there any reason not to initialize the field directly? like
> >>
> >> final Consumer<Msg> readHandler = (Msg obj)-> {
> >>     this.doSomethingWith(obj);
> >>     ...
> >> };
> >
> >
> > You are not allowed to access "this" in a field initializer.
>
> Apparently it is allowed, according to javac.
>
> What's not allowed is to reference a final field that "might not have
> been initialized" when the lambda is constructed; which I think is
> unnecessarily strict and inconvenient for many legitimate use cases.
>
>     final Runnable r = ()->{ this.o.toString(); }; // javac error
>
>     final Object o; // assigned in constructor
>
> It can be worked around by obfuscating `this`
>
>     final Runnable r = ()->{ (this).o.toString(); }; // ok
>
> Zhong Yu
> bayou.io
>
>


More information about the lambda-dev mailing list