Explain Codes LogoExplain Codes Logo

Java Lombok: Omitting one field in @AllArgsConstructor?

java
lombok
constructor-annotations
field-initialization
Alex KataevbyAlex Kataev·Dec 12, 2024
TLDR

To exclude a field from @AllArgsConstructor in Lombok, use @NoArgsConstructor and @RequiredArgsConstructor. Designate fields to include by using final or @NonNull. Without these annotations, the fields will be kept out by @RequiredArgsConstructor. Finally, a custom constructor for compulsory fields can be leveraged:

@Getter @RequiredArgsConstructor public class YourClass { private final int criticalField1; // @RequiredArgsConstructor includes compulsory fields @NonNull private String crucialField2; // Me too! private int excludedField; // Excluded from auto-generated constructors public YourClass(int criticalField1, String crucialField2, int yourField) { this.criticalField1 = criticalField1; this.crucialField2 = crucialField2; // Ah, excludedField, we left you behind. } }

excludedField will only show up in a constructor if you handcraft it.

Choices for mutable and immutable fields

final fields or fields marked with @NonNull will be included within @RequiredArgsConstructor, giving you a set of immutable fields. This can be beneficial when you need stability in your code.

On the other hand, if you have a need for mutable fields, Lombok's @Builder annotation has the flexibility needed. It provides room for excluding fields, making it highly customizable without compromising thread safety.

Initializations: included, excluded, and inline

Be aware of different field initialization strategies provided by Lombok. A field marked as final and initialized inline will not be included in the @AllArgsConstructor generated constructor:

@Getter @AllArgsConstructor public class YourClass { private final int compulsoryField1; @NonNull private String mustHaveField2; private final int leftOutField = 404; // Not Found in @AllArgsConstructor }

leftOutField isn't part of the constructor as it's initialized inline.

Using @Builder for full control

If @RequiredArgsConstructor falls short for your needs, @Builder can be your flexible friend. It provides more control and customization:

@Getter @Builder public class MyClass { private int requiredField1; private String neededField2; // leftOutField doesn't even exist here. Less is more, right? } // Now, create your object with your chosen fields. MyClass mc = MyClass.builder().requiredField1(123).neededField2("Hello").build();

This allows you to build object instances with any combination of fields.

Staying informed & maximizing Lombok

Look over Lombok's documentation regularly to stay abreast of changes and new features. For example, @SomeArgsConstructor is a potential new feature that could allow for custom field exclusion in constructors.

Mixing and matching with Lombok

For complex scenarios where you might need to mix and match different initialization strategies with constructor annotations, consider these cases:

  1. Different Field Initializations: Not all fields need to be initialized through the constructor; default values can also be defined directly within the field declarations.

  2. Using Builders Selectively: When a class has many fields and only a few are mandatory, @Builder.Default provides defaults while allowing custom values for individual objects.

  3. Quasi-Constructors: Are there times when you need to set a field after construction? A factory method could leverage the all-args constructor and then set fields as required.

  4. Mixing Up Annotations: Lombok allows combinations like @NoArgsConstructor, @RequiredArgsConstructor, and custom constructors to achieve complex field behaviors.

Stay updated with Lombok

Stay connected with the Lombok community. Your feedback aids in voting on feature requests like @SomeArgsConstructor and implementing enhancements in new releases. Your toolbox could be more cutting-edge than you think!