Use of @Inherited for class-level annotations?

3,173 views
Skip to first unread message

Sven Linstaedt

unread,
Aug 26, 2010, 5:21:33 AM8/26/10
to Project Lombok
Hello,

I stumbled upon this project - well - about 20 minutes ago. While
thinking about the possible usage scenarios, I had one question in
mind: Have you thought about making the class-level annotations
especially like @NoArgsConstructor being @Inherited so the developer
does not need to specify the annotation on each subtype? Are there any
disadvantages doing so that I did not recognize?

Best regards

Sven

Roel Spilker

unread,
Aug 26, 2010, 5:34:48 AM8/26/10
to Project Lombok
Hi Sven,

thanks for the idea. We have to investigate if this works and if there
are disadvantages.

Roel


On Aug 26, 11:21 am, Sven Linstaedt <sven.linsta...@googlemail.com>
wrote:

Reinier Zwitserloot

unread,
Aug 26, 2010, 9:27:00 AM8/26/10
to Project Lombok
Also, as lombok does not have resolution, we can't actually look at
superclasses, and thus, we can't know that an inherited annotation is
present on a superclass. So, separate from whether or not this is a
good idea (I'm leaning somewhat towards no, as constructors are
traditionally not inherited, so it would seem a bit odd for the
annotations to break that precedent), we can't implement that until we
add resolution abilities, which will probably be a while, as that gets
rather complicated.

On Aug 26, 11:21 am, Sven Linstaedt <sven.linsta...@googlemail.com>
wrote:

Roel Spilker

unread,
Aug 26, 2010, 9:36:04 AM8/26/10
to project...@googlegroups.com
Well, Reinier, I'm not sure we need resolution, since the documentation if @Inherited suggests that the compiler will make sure they are present. But maybe that's only true for runtime annotations.

Still, I'm not sure adding those is a good idea even if we don't need resolution to make it work.

> -----Oorspronkelijk bericht-----
> Van: rein...@gmail.com
> [mailto:project...@googlegroups.com] Namens Reinier Zwitserloot
> Verzonden: 26 August 2010 15:27
> Aan: Project Lombok
> Onderwerp: [project lombok] Re: Use of @Inherited for
> class-level annotations?

> --
> You received this message because you are subscribed to the
> Google Groups group for http://projectlombok.org/
>
> To post to this group, send email to
> project...@googlegroups.com To unsubscribe from this
> group, send email to
> project-lombo...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/project-lombok?hl=en
>
>

Reinier Zwitserloot

unread,
Aug 26, 2010, 9:41:49 AM8/26/10
to project...@googlegroups.com
We definitely need resolution. If the compiler ensures they are copied over, then surely the compiler can't magically do this without it doing the resolution first (i.e. they are copied somewhere in a late phase, such as the compile step). We run after the parse phase. The compiler couldn't possibly know that an @Inherited annotation is on a superclass any more than we can!

 --Reinier Zwitserloot

Maaartin

unread,
Aug 26, 2010, 6:47:39 PM8/26/10
to Project Lombok
On Aug 26, 11:21 am, Sven Linstaedt <sven.linsta...@googlemail.com>
wrote:
I don't think the constructor annotations should be inherited at all.
As Reinier already said, constructors don't get inherited, and while I
can imagine this to be useful sometimes, it shouldn't be the default.
I'd prefer something like
@NoArgsConstructor(inherited=true)
with inherited=false by default, where the inheritance chain would be
handled by Lombok itself.

However, I'm not convinced this could be really useful, are you?

Sven Linstaedt

unread,
Aug 28, 2010, 11:42:23 AM8/28/10
to Project Lombok
@NoArgsConstructor(inherited=true) sounds reasonable to me, if compile-
time annotations can not be inherited. Would these extension also be
applied to @RequiredArgsConstructor and @AllArgsConstructor?

br, Sven

Reinier Zwitserloot

unread,
Aug 28, 2010, 2:32:30 PM8/28/10
to Project Lombok
I'm still not sure we'd even introduce this feature. We have a rule
that any feature that requires a parameter on one of the annotations
must be significantly more important than a set of features we've
already discussed and which also seem useful in niche circumstances.
The reasoning for this is, if the feature being discussed is really
not much better than the set of features we've already thought up
ourselves, then the only logical conclusion is that ALL these features
will need to be added in time. Which would mean that i.e.
@NoArgsConstructor will end up with 45 parameters, which we've already
agreed on is worse than not having the features in the first place.

A feature should (A) bust boilerplate which is either very wordy or
easy to get wrong, and (B) be applicable relatively often. Because
that's what lombok does: It busts common boilerplate that's hard to
write. It does not aim to turn java into a new language. At the very
least, that's what @Data, @NoArgsConstructor, etc. all do. We may at
some point add features that don't fit the "Busts common, hard-to-
write boilerplate" model, but definitely never under those
annotations.

So far I don't see why inherit = true is any more special than, say,
usePrivateInitializerMethod, nullcheckAllArgs, logCalls,
transformer="methodName", etc.

On Aug 28, 5:42 pm, Sven Linstaedt <sven.linsta...@googlemail.com>
wrote:

Sven Linstaedt

unread,
Sep 15, 2010, 8:43:55 AM9/15/10
to Project Lombok
Sorry for the delayed response. I was forced to celebrate someones
30th.

I have asked for this feature actually because of the two reasons (A
+B) mentioned by Reinier. When dealing technical frameworks which
enable extension by inheritance of framework given classes (e.g. JSF
or Seam) , you (the dev) often need to remember delegating the
parametrized constructor call to the super type. E.g. for

abstract class Identifier {
final Long id;

Identifier(Long id) {
this.id = id;
}

Identifier() {}
}

class Form1Identifier extends Identifier {
FormIdentifier(Long id) {
super(id);
}
}

it would be nice if one can write a more robust and dev-friendly
version like

@AllArgsConstructor(inherited = true)
@NoArgsConstructor(inherited = true)
abstract class Identifier {
final Long id;
}

class Form1Identifier extends Identifier {
}

If the super type also has a default constructor (many frameworks
require this) the compiler does not even warn you about the missing
delegate constructor, so you end up getting some exception running the
application when framework tries to initilialize the configured class
with parameters.

So in reference to Reinier's arguments inheritance of lombok's
constructor related annotations would
(A) reduce boilderplate and the chance to mess up the application by
eliminating the requirement to explicit create delegate constructors
(B) is applied in places where technical inheritance if used for
enabling extension (e.g. the beforementioned JSF and Seam)

wdyt?


br, Sven

Reinier Zwitserloot

unread,
Sep 15, 2010, 10:09:31 PM9/15/10
to Project Lombok
Any boilerplate which is rare in normal java code, but common when
working with a specific library is something we'd rather support by
way of a unique annotation that is put in a package that reflects its
design to work with that specific library. We don't have any yet, but,
at least I'm not opposed to such an idea (Roel is on vacation, so
can't ask him what he thinks. I recall we discussed this before and
agreed on this, though). However, this situation is different.

Let's have a closer look:

Form1Identifier is to get 2 constructors, both generated by lombok,
one of which is to take no arguments, and which is to call the no-args
super constructor. The other constructor is to take all fields in
Form1Identifier as parameters, *AND*, on top of that (and in front of
them), all constructors from the some-args constructor in the
superclass.

That sounds random to me. Remember that the superclass may have 20
constructors as far as we know. Why should AllArgsConstructor call
that specific constructor? Only because that constructor so happens to
have been generated by lombok with the same annotation, and an
inherit=true stuck onto that? We can't actually tell that happened,
lombok annotations are source retention only, and the constructors are
by design indistinguishable from a handwritten one.

So, should AllArgsConstructor take the some-args constructor because
its the constructor of the superclass with the most parameters on it,
and "AllArgsConstructor" more or less implies that it should go for
the most parameters? Maybe, with an error if there's more than 1
constructor with that number of parameters in the super? This feels
arbitrary to me, and that's bad: A programmer doesn't know which
constructor lombok has taken until he opens up the lombok
documentation, that's a failure of API design. We could let you
explicitly name the constructor you want, but now you're programming
in lombok-specific annotation DSL language, instead of in java. You
save only a handful of characters now, lombok isn't really delivering
a lot of value in such a situation.

In my opinion, forcing a programmer to create a large class hierarchy,
each class having multiple constructors is just disastrous. I know of
no API built around a complex hierarchy that's anything but a
clusterfail (example: swing!). These kinds of headaches start popping
up.

This problem should have been solved by making Identifier (which is
hopefully abstract!) an interface, and then all you really need to do
is put:

private Long id;

in every subclass, which is some boilerplate but manageable, and it
does greatly help clarity: Every class is responsible for its own id.
Because all these classes implement Identifier, you can use getId()
and setId() on any identifier instance. You've also removed a lot of
the class hierarchy: You've just got a bunch of XIdentifier classes,
which all have no superclass (well, java.lang.Object). They do all
implement the Identifier interface though, so you can generalize them.

Incidentally, as I've explained earlier in this thread, lombok needs
resolution to look at the constructors of parent classes, and it
currently doesn't, so we couldn't build this feature even if it didn't
have all these problems associated with it.


On Sep 15, 2:43 pm, Sven Linstaedt <sven.linsta...@googlemail.com>
Reply all
Reply to author
Forward
0 new messages