I don't like @Builder much. It makes the .class bigger, it doesn't allow inheritance, the resulting code is short but not too nice.
Often the only argument for @Builder is that it ensures immutability, for which the only other option is all args constructor (which @Builder uses internally).
Hereby I suggest another approach, a "seal" interface - which would only have getters. It would work like this:
@Sealable
@Getter
@Setter @Accessor(chain = true)
class Foo { private int x; }
The @Sealable would create this:
interface Foo { public int getX(); }
class FooImpl implements Foo {
private int x;
...
public Foo seal() { return this; }
}
And could be used this way:
Foo foo = new FooImpl().setX(1).seal();
Obviously, the seal() method is not necessary, but creates dev-friendly way to get the type rather than having to look it up / write the type / change the type. Also, it could be overriden to perform some additional operations before returning the object (validation, ...).
Also, I assume it's not possible / advisable to swap the class names like this. It could possibly rather be the other way - class Foo and interface FooSeal, or maybe Foo.Seal as a inner type.
Foo.Seal foo = new Foo().setX(1).seal();
I think that this is doable by using @Value, @Wither and @AllArgsConstructor.
An annotation that changes class Foo into interface Foo and magically creates a class FooImpl whose source is in Foo.java would be, to me, extremely _surprising_ behavior. It's one thing to add nested classes, but please don't completely violate conventions for top-level types.
@OndraZizka I guess, a better starting point would be the interface and you'd just generate the immutable implementation of it. But that's actually simpler than what Lombok does, as it only requires creating a new class rather than modifying existing code. See AutoValue and FreeBuilder, if that's what you want.
I don't see this happening.
@wrprice Thanks for the comment. Have you read the whole post? If not, let me point to the relevant part:
Also, I assume it's not possible / advisable to swap the class names like this. It could possibly rather be the other way - class Foo and interface FooSeal, or maybe Foo.Seal as a inner type.
Ok I admit I haven't put the idea the right way. Seems like the rejection isn't about the idea, but about the particular implementation I suggested.
Since I can't reopen this, I will reword the RFE in a new issue, unless @rspilker confirms that he doesn't like the idea of a Lombok feature to provide a method to "seal" an object (to return an immutable representation of it, whether it's a limiting interface, a proxy, a copy in a subclass overriding setters, an internal flag for setters...).
Thanks for the comment. Have you read the whole post?
If not, let me point to the relevant part ...
@OndraZizka, yes, I read it. My comment regarded the part(s) I find most objectionable; I meant what I said, and I said what I meant. (And no more than that.) If you'd like to know my opinion on the portion you quoted, it is:
Finally, my opinion doesn't mean terribly much. I'm just a user.
Most helpful comment
I don't see this happening.