On Tuesday, November 13, 2012 2:52:31 PM UTC+1, GreenEyed wrote:
Would @Constructor(noArgs=true) really be necessary? That would only seem to be needed when the default constructor would add some fields that are required... which means they are final, so a constructor not initialising them would not make sense... right?
I might have missed some corner case as I usually just use the default one :D.
You have (as I nearly have when writing this). "required" means required due to `final` or due to `@NonNull` and ignoring the latter makes sense.
On Tuesday, November 13, 2012 1:34:09 PM UTC+1, Reinier Zwitserloot wrote:
Do we want:
@Constructor(allArgs=true)
@Constructor(noArgs=true)
@Constructor (this is the default - and is the current @RequiredArgsConstructor)
@Constructor(includes={"field1", "field2"})
@Constructor(excludes={"field1", "field2"})
With all these options being mutually exclusive,
I'd say the first two are just like `@Constructor(includes={})` and `@Constructor(excludes={})`, respectively. It's not really obvious to exclude nothing if you want them all, but I could get used to it. There could be a problem with the default annotation values, however, it's something you can solve IIRC. Still, it's ugly, so I'm not really proposing it.
Obviously, the base for `excludes` should be "all". But what should be the base for `includes`? You must include all final fields, so you don't want to mention them explicitly, do you? Should be @NonNull non-final fields be included by default, too? If so, you may want to *both* exclude and include:
@Constructor(include="a", exclude="b")
class C {
int a; // was included explicitly
@NonNull int b; // was excluded explicitly
@NonNull int c; // is included by default (assuming the base is "all required")
final int d; // is always in and can't be excluded
}
This is quite ugly, I know.
or do we want to keep the current 3 annotations and add a 4th with the includes/excludes?
The 5 above options are exclusive, but you might need multiple constructors. The easiest way is probably to stick with multiple annotations. I could propose an ugly alternative:
@Constructor(excludes={"field1", "field2"}, allArgs=true, noArgs=true)
which would be a compact way to define 3 constructors. However, this leaves no place for defining `accessLevel`, `staticName`, or annotations (which we all hope will come again), unless you want them the same for all generated constructors. But you surely *do not* want to place `@Inject` on multiple constructors.
For all this include/exclude stuff (it's also part of @ToString etc), it feels bad that these are stringly typed. We could move to unique excludes annotations that exist inside @ToString etc, so then it would look like:
@Constructor
public class Test {
@Constructor.Exclude private int unid;
private String name, address, description, comment;
private int age;
}
This looks much nicer, but what if you need multiple constructors? Assuming the `@Constructor.Exclude` annotation works with the new `@Constructor` only and the three old constructor annotation are still available, it should suffice.
note that, annoyingly, eclipse's auto-fix imports will turn this into just @Exclude along with an "import lombok.Constructor.Exclude;" statement, not really what we're looking for.
Eclipse loves to import nested classes although it's rarely a good idea. Calling it `@lombok.Exclude.Constructor` could help here, but it feels a bit strange (OTOH "exclude something" is correct English, not the other way round).