Lombok: Feature request: Seal interface

Created on 6 Apr 2018  路  7Comments  路  Source: projectlombok/lombok

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();

Most helpful comment

I don't see this happening.

All 7 comments

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:

  • Your initial proposal probably would have been better had you applied one of these alternatives rather than listing them as afterthoughts at the end.
  • That said, I also don't particularly care for those _specific_ alternatives.
  • There probably _is_ a reasonable approach; I'm not arguing against _immutable objects_ in the abstract.

Finally, my opinion doesn't mean terribly much. I'm just a user.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lludwa picture lludwa  路  3Comments

merric picture merric  路  4Comments

lombokissues picture lombokissues  路  3Comments

iskigow picture iskigow  路  3Comments

rspilker picture rspilker  路  3Comments