Describe the feature
@NoArgsConstructor annotation could be somehow configured to initialize collection fields to the correct empty collection.
Currently, it initializes them to null. Using @Singular annotation on the collection field does not change the behaviour.
Maybe I am missing something, but I cannot find references regarding this anywhere, sorry for the confusion in case.
Describe the target audience
Everyone wanting to mix the convenience of the annotation with the safety of initializing collections to the correct empty collection at object creation time.
Additional context
Currently only workaround seems to be implementing the no arg constructor ourselves.
The problem with trying to silently initialize fields to a sentinel/blank value is threefold:
ImmutableList? We can't look at the inside of that class def, and even if we could, there is no convention or interface to identify 'call this static method'. I guess we could call just new FOO(); for a field defined as FOO x, whatever FOO might be, but that's in fact the wrong thing to do in many cases: List<String> x = new List<String>(); does not compile.The only real solution is either that you specify the expression to generate a blank, which defeats the point (that's more boilerplate than we replace!), or that we build in a giant library of type to known blank expressions, which is a lot of work and then means that anybody reading code has to guess if we included the 'blank expression mapping'.
We can solve a lot of these issues by introducing an annotation: Now the first 2 problems are solved, and at least for the third, if we don't know how to do it we can just generate a warning.
That's a plausible road to go here, but @Singular doesn't really fit the role. That's for builder, and 'initialize this to a blank value' makes no sense either.
No, the right annotation must be: @NonNull, I think. However, we already do this; if you enforce a no-args-constructor when nonnull fields are involved, we.. still make them null, because, hey, you asked, and that actually meshes with the use case (initializing objects which then get immediately filled, for example via setters, by some framework, such as JPA/Hibernate).
I'll discuss with @rspilker if we want to change (and in that sense, break backwards compatibility); we have a minor break release (1.20) planned. If this misses the boat you're in a for a long wait.
Hello and thank you for the fast reply.
I understand your points, and was actually more investigating whether this was an already available functionality that I somehow could not use properly, or simply a missing feature, which you confirmed to be the case (thanks).
As for your comments:
true, the difference being that null might lead more easily to NullPointerException, while an empty collection is usually handled more gracefully in the application code.
also true, but as you noted in your point 3, you would not be able to provide a default for every collection anyway, therefore you would need to receive some input, maybe via some arguments provided to the annotation, making it backwards-safe (no arguments provided means the old behaviour persists)
I agree with your analysis, and am currently handling the case by implementing the empty constructor myself; however as you stated, although difficult, it might not be impossible if the developer himself provides the necessary empty constructor. In terms of clutter this approach might be as much as actually writing the method directly (although nobody does it anymore, that's why we love lombok ;) )
Anyway, I am not in dire need of such a feature, so from my side I wouldn't want to rush it since the workaround is not painful or difficult to use.
Thank you again and have a nice day
An alternate way to go is that we disentangle @Builder.Default from builder and just make it a top-level (in the lombok package) annotation named Default which is then used for builder, noargsconstructor, and perhaps other things too. I don't think it's sensible to offer a way to provide different defaults, so the fact that you're inherently limited to only a single value is no big deal.
I assume this would be to your liking, if it would work:
@NoArgsConstructor @AllArgsConstructor
class Example {
@lombok.Default com.google.guava.collect.ImmutableList names = ImmutableList.of();
}
would gen:
class Example {
com.google.guava.collect.ImmutableList names;
public Example() {
this.names = ImmutableList.of();
}
public Example(ImmutableList names) {
this.names = names;
}
}
Making Default a top level annotation makes sense. It would mesh well with
the new Jacksonize annotation too.
If we do this, would you deprecate the Builder variant or leave it as is?
On Thu, Mar 5, 2020, 20:40 Reinier Zwitserloot notifications@github.com
wrote:
An alternate way to go is that we disentangle @Builder.Default from
builder and just make it a top-level (in the lombok package) annotation
named Default which is then used for builder, noargsconstructor, and
perhaps other things too. I don't think it's sensible to offer a way to
provide different defaults, so the fact that you're inherently limited to
only a single value is no big deal.I assume this would be to your liking, if it would work:
@NoArgsConstructor @AllArgsConstructorclass Example {
@lombok.Default com.google.guava.collect.ImmutableList names = ImmutableList.of();
}would gen:
class Example {
com.google.guava.collect.ImmutableList names;public Example() { this.names = ImmutableList.of(); } public Example(ImmutableList names) { this.names = names; }}
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/rzwitserloot/lombok/issues/2390?email_source=notifications&email_token=AABIERJHS6KQZJY33VL7VVLRF752ZA5CNFSM4LCHW3QKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEN6T27Y#issuecomment-595410303,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AABIERI4ZUHNWWYPCGE3HRDRF752ZANCNFSM4LCHW3QA
.
Probably deprecate it, yeah. Maybe wait a version of 2, because otherwise people with a 'split' codebase (half of the devs on some codebase are on lombok 1.18.10, the others on 1.20) would be forced to either check something in that doesn't work at all for half the users, or to check in something that gens deprecation warnings for half the users.
So, about a year in, then we deprecate the old. Maybe one day we remove it entirely.
Messing with @Builder.Default should be done together with issue #2340 .
I was just coming to look for this exact issue! What is the status of this feature?
I'd also like to throw an idea in that we could simply add it as an option to the @NoArgsConstructor (e.g. something like setCollections=EMPTY_LIST then the default is setCollections=NULL where EMPTY_LIST and NULL are enums to be imported).
Having the @Default option at the top level is also pretty great, since it could apply to @NoArgsConstructor and @RequiredArgsConstructor
Most helpful comment
An alternate way to go is that we disentangle
@Builder.Defaultfrom builder and just make it a top-level (in the lombok package) annotation namedDefaultwhich is then used for builder, noargsconstructor, and perhaps other things too. I don't think it's sensible to offer a way to provide different defaults, so the fact that you're inherently limited to only a single value is no big deal.I assume this would be to your liking, if it would work:
would gen: