170

If I specify @AllArgsConstructor using Lombok, it will generate a constructor for setting all the declared (not final, not static) fields. Is it possible to omit some field and this leave generated constructor for all other fields?

user3656823
  • 1,703
  • 2
  • 10
  • 4

7 Answers7

208

No that is not possible. There is a feature request to create a @SomeArgsConstructor where you can specify a list of involved fields.

Full disclosure: I am one of the core Project Lombok developers.

TuGordoBello
  • 4,350
  • 9
  • 52
  • 78
Roel Spilker
  • 32,258
  • 10
  • 68
  • 58
177

Alternatively, you could use @RequiredArgsConstructor. This adds a constructor for all fields that are either @NonNull or final.

See the documentation

Paolo Stefan
  • 10,112
  • 5
  • 45
  • 64
dermoritz
  • 12,519
  • 25
  • 97
  • 185
  • 1
    This is a nice workaround, using @NonNull. But be aware that this does not work with fields having default-values. – eeezyy Jun 28 '19 at 14:50
  • 1
    This worked well for me, and I even marked the omitted field with `@Transient` to avoid it being tracked by java persistence layer since it was in my DAO. – Encryption Jan 13 '20 at 14:43
29

Just in case it helps, initialized final fields are excluded.

@AllArgsConstructor
class SomeClass {
    final String s;
    final int i;
    final List<String> list = new ArrayList<>(); // excluded in constructor
}

var x = new SomeClass("hello", 1);

It makes sense especially for collections, or other mutable classes.

This solution can be used together with the other solution here, about using @RequiredArgsConstructor:

@RequiredArgsConstructor
class SomeClass2 {
    final String s;
    int i; // excluded because it's not final
    final List<String> list = new ArrayList<>(); // excluded because it's initialized
}

var x = new SomeClass2("hello");
Ferran Maylinch
  • 10,919
  • 16
  • 85
  • 100
  • 4
    Important addition: "initialized **final** fields are excluded" -> If the field is only initialized but not final the constructor (generated by AllArgsConstructor) will be generated with this field as well :) – oruckdeschel Jan 06 '21 at 09:21
  • Hi I wanna ask if there's any idea how to generate two types of constructors, for example one contains string s and int i and one contains string s and string F . – Compte Gmail Oct 31 '21 at 11:00
  • 1
    Lombok is intended to generate code for common cases, not for specific scenarios. You should code your particular constructors explicitly. – Ferran Maylinch Nov 01 '21 at 19:23
  • 1
    Your answer helped a ton: in case the fields you want to exclude are final because they are constants. – avi.elkharrat Dec 16 '21 at 10:07
  • 1
    I used this option and it works. – Park JongBum Dec 15 '22 at 06:38
  • 1
    To me this answer is underrated and should be first looked by anyone searching answer on how to skip a field in lombok constructor. – Bryn Feb 24 '23 at 11:02
17

A good way to go around it in some cases would be to use the @Builder

TuGordoBello
  • 4,350
  • 9
  • 52
  • 78
enkara
  • 6,189
  • 6
  • 34
  • 52
  • see an example here: https://stackoverflow.com/a/39920328/363573 – Stephan Apr 12 '20 at 16:51
  • 2
    Lets say "_a_ way" but not "a _good_ way". If you want an `AllArgsConstructor` to guarantee that the user provides all (required) members a std builder is _not_ the way to do it. – towi Jul 01 '21 at 09:32
  • 1
    I said in some cases, and I still stand by it – enkara Jul 02 '21 at 11:51
13

This can be done using two annotations from Lombok:

Please find the example as follows:

package com.ss.model;

import lombok.*;

@Getter
@Setter
@RequiredArgsConstructor
@ToString
public class Employee {

    private int id;

    @NonNull
    private String firstName;

    @NonNull
    private String lastName;

    @NonNull
    private int age;

    @NonNull
    private String address;
}

And then you can create an object as shown below:

Employee employee = new Employee("FirstName", "LastName", 27, "Address");
informatik01
  • 16,038
  • 10
  • 74
  • 104
0

Lombok is meant to take care of the boilerplate code for your POJOs. Customized constructors/setters/getters/toString/copy etc are not on the boilerplate side of code. For these cases, every Java IDE provide easy to use code generators to help you do things in no time. In your case a

public MyClass(String firstName, String lastName) {....}

is much more readable and makes more sense than a hypothetic:

@AllArgsConstructor(exclude = "id", exclude = "phone")

Have fun!

0

When you needs a constructor with just some attributes, you can use

@RequiredArgsConstructor at class level and declare the choosed attributes as final. Then, if you need an empty constructor, you can use something like

@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)

This annotation will create an empty JPA's constructor and the attributes will be initialized with default values (0 for int, null for String and so on).

Example:

@Data
@Entity
@Table(name = "VetFiles")
@RequiredArgsConstructor
@NoArgsConstructor(access=AccessLevel.PRIVATE, force=true)
public class FileInfo implements Serializable {

    private static final long serialVersionUID = 6719621520531075147L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private final String name;
    private final String url;

    @ManyToOne
    private Thing thing;
lm2a
  • 835
  • 1
  • 10
  • 19