@Wither with subclasses

870 views
Skip to first unread message

Fabrizio Giudici

unread,
Feb 4, 2013, 10:52:16 AM2/4/13
to Project Lombok
Most of my builders should be written as:

@RequiredArgsConstructor @Immutable @Wither
public static class Builder
{
private final Path file;

private final String signature;

private final DateTime scanDateTime;

public Builder()
{
this(null, null, null);
}

@Nonnull
public ScannedFile build()
{
final ScannedFile scannedFile = new ScannedFile(file,
signature, scanDateTime);
register(scannedFile);
return scannedFile;
}

protected void register (final @Nonnull ScannedFile scannedFile)
{
}
}


where the register() method is thought to be overridden by the built
object owner, e.g.:

@Override @Nonnull
public ScannedFile.Builder addScannedFile()
{
return new ScannedFile.Builder()
{
@Override
protected void register (final @Nonnull ScannedFile
scannedFile)
{
scannedFileMapByPath.put(scannedFile.getFile().getFileName(),
scannedFile);
}
};
}

Unfortunately, this doesn't work since @Wither correctly creates a new
object, but always of the base class.

public SELF_TYPE withFoo(int foo) {
return this.foo == foo ? this : new SELF_TYPE(otherField1,
otherField2, foo);
}


I'm proposing two ways of extending it:

1. The best approach would be for Lombok to generate something as:

public SELF_TYPE withFoo(int foo) {
return this.foo == foo ? this :
getClass().getConstructor(...).newInstance(otherField1, otherField2, foo);
}

where the ellipsis are indeed filled with the proper metaclasses.

2. An alternate approach could be to search for a static newInstance()
method, with the proper parameters, that could be provided by the user. If
it doesn't exist, Lombok would fall back to the current behaviour.

But #1 seems to me the best approach at all.

--
Fabrizio Giudici - Java Architect @ Tidalwave s.a.s.
"We make Java work. Everywhere."
http://tidalwave.it/fabrizio/blog - fabrizio...@tidalwave.it

Reinier Zwitserloot

unread,
Feb 5, 2013, 10:05:50 AM2/5/13
to project-lombok
I'm extremely hesitant to throw reflection around. That means you can't use this with GWT, for starters. We did discuss back when we added @Wither that we need to make it possible to specify your own 'constructor', but decided that we can always add it later. You're the first to need it, so that might happen at some point.

Searching for a 'magic name' method is another thing that we really don't want to start doing. It makes lombok way too opaque. Something like @Wither(using = "newInstance"), that might happen, or, a @UseForWither annotation that you stick on your newInstance method.

 --Reinier Zwitserloot


--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombok+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Fabrizio Giudici

unread,
Feb 5, 2013, 10:25:19 AM2/5/13
to project-lombok, Reinier Zwitserloot
On Tue, 05 Feb 2013 16:05:50 +0100, Reinier Zwitserloot
<rei...@zwitserloot.com> wrote:

> Searching for a 'magic name' method is another thing that we really don't
> want to start doing. It makes lombok way too opaque. Something like
> @Wither(using = "newInstance"), that might happen, or, a @UseForWither
> annotation that you stick on your newInstance method.

Both would be fine. Perhaps @UseForWither is cleaner from the readability
point of view.

Anthony Whitford

unread,
Feb 10, 2013, 12:09:32 PM2/10/13
to project...@googlegroups.com
Perhaps it is worth revisiting Issue 16:  Add a @Builder annotation for the builder pattern.

I am generally happy with the @Wither annotation -- I use it for "mutating" immutable objects.
I am still in need of a nice @Builder annotation that can generate a clean builder implementation for a @Value class.
(This would be particularly valuable to me since I am in desperate need to shift almost all of my shared data towards immutable objects to avoid locking issues and produce more performant code.) 

Peichhorn has the lombok-pg project on github with a @Builder annotation, but I am hesitant to use it for a few reasons:
  1. The latest "release" is for Lombok 0.11.3, but I am using Lombok 0.11.6; I am concerned about compatibility issues either now or going forward, and its lack of a release for 0.11.4 or 0.11.6 make me wonder about how much attention it is getting
  2. The documentation needs some work (lots of TODOs remain)
  3. An unrelated project could end up colliding with the core Lombok (imagine both offer a @Builder pattern, but a little different)



Reinier Zwitserloot

unread,
May 8, 2013, 11:04:16 AM5/8/13
to project-lombok
Allright guys, loud and clear. We'll push @Builder up the agenda.

 --Reinier Zwitserloot


On Wed, May 8, 2013 at 12:02 PM, castorm <cas...@gmail.com> wrote:
I'd also enjoy a @Builder annotation, I found the constructor annotations insufficient. I don't think the @RequiredArgsConstructor approach fits the usual scenario, it should be better covered by a Builder pattern.

Just my opinion ;)

Great work in the project, I love it! :)

--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombo...@googlegroups.com.

Fabrizio Giudici

unread,
May 8, 2013, 11:49:01 AM5/8/13
to project-lombok, Reinier Zwitserloot
On Wed, 08 May 2013 17:04:16 +0200, Reinier Zwitserloot
<rei...@zwitserloot.com> wrote:

> Allright guys, loud and clear. We'll push @Builder up the agenda.

Awesome. Furthermore, this kind of stuff is something very valuable in the
long run, as it won't never be in a JDK, such as extension methods,
closures, etc...

eric.giese

unread,
May 9, 2013, 6:20:23 AM5/9/13
to project...@googlegroups.com, Reinier Zwitserloot
I'd say extension methods won't be in the JDK as well.
There is not that much value in this syntactic sugar, and the Java community has already been conservative.
Sad. :-(

JDK8 gains the defender/default/extension/whatever methods for interfaces.
But they are more like yet another form of limited multiple inheritance.
Reply all
Reply to author
Forward
0 new messages