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