A request: chainable setters

9 views
Skip to first unread message

Michael Lorton

unread,
Sep 6, 2009, 6:33:36 AM9/6/09
to project-lombok
Chainable setters are a big convenience when you have a lot of optional parameters.  If you write:

class Window {
   // ..
   public Window setHeight(int height) {
       this.height = height;
       return this;
   }  
   public Window setBorder(int border) {
       this.border = border;
       return this;
   }  
   // ...

}

then you can do graceful things like

    return new Window().setHeight(25).setBorder(1).setThis().setThat()....


What I'm asking for is a parameter "chainable" for  @Data and @Setter.  A chainable setter returns this instead of void; a chainable data class makes all its setters chainable.

M.

Jacek Furmankiewicz

unread,
Sep 6, 2009, 7:33:10 AM9/6/09
to Project Lombok
+1 from me, although I would prefer to think of this in more general
terms, so that we could have chainable
setters on non-Lombok annotated classes, such as Swing controls...now
those really need chainable setters.

Michael Lorton

unread,
Sep 6, 2009, 7:47:05 AM9/6/09
to project...@googlegroups.com
Wow, I haven't done Swing for a decade at least but I assumed that it had chainable setters (how can you have a UI system without them -- that's why I used Window in my example).  Probably too late to get it implemented now, but maybe we should come up with a new naming standard for chainable setters, other than setX(), since Java can't overload on return value, something like withX() or settingX() or andX().

M.

Roel Spilker

unread,
Sep 7, 2009, 5:35:22 AM9/7/09
to Project Lombok
We intend to implement this using the @Builder annotation. If you
apply it to a class Foo it will probably generate an innerclass
FooBuilder. FooBuilder will have setters that return the builder. And
also addX and putX methods to fill lists and maps.

For an example you can have a look at the generated code for messages
using the protoc compilter for protocol buffers (http://
code.google.com/intl/nl/apis/protocolbuffers/docs/reference/java-
generated.html#message). The documentation does not really show the
builders; you should try to actually generate the code to get a good
feel.

On Sep 6, 1:47 pm, Michael Lorton <mich...@circuspop.com> wrote:
> Wow, I haven't done Swing for a decade at least but I assumed that it had
> chainable setters (how can you have a UI system without them -- that's why I
> used Window in my example).  Probably too late to get it implemented now,
> but maybe we should come up with a new naming standard for chainable
> setters, other than setX(), since Java can't overload on return value,
> something like withX() or settingX() or andX().
>
> M.
>

Jacek Furmankiewicz

unread,
Sep 7, 2009, 10:39:32 AM9/7/09
to Project Lombok
Would you be able to apply @Builder on non-Lombok classes? That would
be killer.

*maybe through a JDK proxy or something along those lines*

Michael Lorton

unread,
Sep 7, 2009, 11:01:20 AM9/7/09
to project...@googlegroups.com
If @Builder took as an argument another, unannotated class, and meant that all setX methods would be updated to return this, it would be a extension of the Decorator pattern.  You could write:

class SomeExistingClassInALibrary {
    SomeExistingClassInALibrary(int z);
    int getX();
    void setX(int x);
    void someOtherMethod();
}


@Decorator(SomeExistingClassInALibrary.class, builder=true)
class MyIncrediblyUsefulNewClass {

}

would generate

class MyIncrediblyUsefulNewClass {
     private final inner;
     MyIncrediblyUsefulNewClass(int z) {
          inner = new SomeExistingClassInALibrary(z);
     }
     int getX() { return inner.getX(); }
     MyIncrediblyUsefulNewClass  setX(int x) {
         inner.setX(x); return this;
     }
    void someOtherMethod()  {
         inner.someOtherMethod();
     }
}

If builder were *false*, the new class would implement all the interfaces the old one did, but wouldn't have the cool chainable semantics.  With builder set to "true" it can only implement the interfaces that lack any setters.

M.

Roel Spilker

unread,
Sep 7, 2009, 11:59:42 AM9/7/09
to Project Lombok
If you apply @Builder to non-Lombok classes, we need to be ably to
"understand" the constructor.

Actually, adding @Builder would make it a Lombok class :-) We should
probably only allow it if Lombok can generate a special constructor,
maybe a private constructor that has the Builder as the only
parameter.

Roel Spilker

unread,
Sep 7, 2009, 12:03:10 PM9/7/09
to Project Lombok
Currently, Lombok cannot use any information that is not in the
current class. So implementing another interface is regrettably not
possible. We hope to implement this feature soon, because it also
"unlocks" other useful features, like delegates.
Reply all
Reply to author
Forward
0 new messages