let's play TDD, tackles closures in java

Alessio Stalla alessiostalla at gmail.com
Mon Dec 20 08:11:55 PST 2010


On Mon, Dec 20, 2010 at 5:02 PM, Tom Hawtin <tom.hawtin at oracle.com> wrote:
> On 20/12/2010 10:42, Brian Goetz wrote:
>>> The long, special-purpose way around, using anonymous inner classes (or
>>> local classes), is actually rather easy.
>>>
>>>      new XyzListener() {
>>>          private boolean fired;
>>>          public void event(XyzEvent event) {
>>>              fired = true;
>>>          }
>>>          {
>>>              abc.addXyzListener(this);
>>>              abc.doThing();
>>>              assertTrue(fired);
>>>          }
>>>      }
>>
>> Yuck.  Not only does it use the hard-to-read instance initializer feature, but it allows the 'this' reference to escape during construction, which is a no-no.
>
> It's going to be a compromise in the battle against Java's generally
> verbose syntax. The instance initialiser in a tiny anonymous inner class
> looks fine to me. In this case, I don't care that `this` escapes the
> instance initialiser to the enclosing method.
>
> If actual Java wasn't so verbose, what I'd like to write is something like:
>
>     declare listener = new XyzListener() {
>         private boolean fired;
>         public void event(XyzEvent event) {
>             fired = true;
>         }
>     };
>     abc.addXyzListener(listener);
>     abc.doThing();
>     assertTrue(listener.fired);
>
> The previous code was what is necessary and sufficient to translate this
> into reasonable, real code.

Well, you can approximate that better with

class MyXyzListener extends XyzListener {
    private boolean fired;
    public void event(XyzEvent event) {
        fired = true;
    }
}
MyXyzListener abc = new MyXyzListener();
...use abc...

it's a little more verbose, but it avoids anonymous class/constructor
magic. People often forget that you can declare named classes that are
local to a method.

> What I believe should be avoided is a lurch away from OO with the
> listener data being split from the listener into the enclosing context.
>
> Of course, you don't want to repeat this sort of code for every single
> possible `doThing(args)`.
>
> Tom
>
>


More information about the lambda-dev mailing list