Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@AllArgsConstructor Is Dangerous! #2094

Closed
mcmonster opened this issue Apr 10, 2019 · 6 comments
Closed

@AllArgsConstructor Is Dangerous! #2094

mcmonster opened this issue Apr 10, 2019 · 6 comments

Comments

@mcmonster
Copy link

The Problem

@AllArgsConstructor seemingly generates the order of constructor arguments based on the position of fields within the actual source file. If one has two fields with the same type, the seemingly innocuous change of switching the declaration order will produce compile-able, but buggy code as the constructor arg order is now changed.

The Solution

Generate arg order using something more predictable, such as alphabetical ordering; or better yet, deprecate @AllArgsConstructor :)

@randakar
Copy link

randakar commented Apr 10, 2019 via email

@janrieke
Copy link
Contributor

I think it's implemented this way on purpose. It is reasonable to let the parameter order follow the order of field declarations.
Using any other order has exactly the same drawback: For instance, if the annotation would use alphabetical ordering, renaming a field could similarly create a compatible constructor.
Deprecating is also clearly not an option, as so many developers rely on this feature. If you feel this annotation is too dangerous, then simply switch it off in your project by lombok.allArgsConstructor.flagUsage = error.

@nkavian
Copy link

nkavian commented Jun 22, 2021

There's no easy answer on this topic, but I'm in the camp that this feature is dangerous. This essentially shifts compile time errors into runtime bugs. I avoided scripting languages like NodeJs, PHP, Ruby on Rails because I don't want runtime headaches. I'm an experienced developer, so personally, this feature is not dangerous to me. It's in consideration to an ecosystem that includes millions of junior developers as well as enterprises that already struggle enough with code quality. This annotation is simply a loaded gun..

@jnk1m
Copy link

jnk1m commented Apr 3, 2023

This is a matter of perception and preference. Once you know the order of the fields changes the order of the constructor arguments it's actually quite useful to be able to reorder the arguments as you wish. If you want to create your objects in a way that does not depend on the order of the fields, use @Builder

Hi, as a junior developer, I've been struggling with the @AllArgsConstructor and @builder problem. I know that using @AllArgsConstructor may cause issues with reordering arguments or fields. While reading through the official @builder documentation, I came across this part "If a class is annotated, then a package-private constructor is generated with all fields as arguments (as if @AllArgsConstructor(access = AccessLevel.PACKAGE) is present on the class)."
This led me to believe that @AllArgsConstructor is automatically created when I use the @builder annotation. That's why I've been avoiding using @builder and trying to manually write down the builder pattern...
However, if @builder is not concerned with ordering issues, I'm ready to use it. Can you explain how @builder avoids dependency on the order of the fields even though it works as if @AllArgsConstructor is present on the class?
I would really appreciate it if you could help me get rid of this question that's been lingering in my mind for days!
Thanks!

@dstango
Copy link

dstango commented Apr 3, 2023

ˋ@builderˋ needs some constructor with all arguments internally to actually create the resulting object. Yet - as the builder is generated together with the constructor any changes in the parameter order of the fields and thus the constructor are automatically considered and respected. So the generated builder is always in sync with the constructor.

@janrieke
Copy link
Contributor

janrieke commented Apr 3, 2023

You can use @SuperBuilder if you don't want the all-args constructor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants