The @Builder annotation has some odd behavior if you want to add default values (it just hardcodes them and you cannot override them!) or extra builder methods.
Actually, anything involving default values seems to be very brittle and difficult to work with -- especially when deserializing objects from JSON.
The @Wither annotation results in methods that do not always make a copy, and sometimes use == instead of .equals when comparing class members. If you call one of the Wither methods and assume you have a copy of the original object, and then you modify that "copy", you might have just created a very subtle bug.
If you are using IntelliJ you can use the Refactor > Delombok menu option to show you the code that Lombok generates. I've been told that does not actually invoke the same code that the annotation processor invokes at compile time, so the results of Delombok might be misleading.
Yeah, but what if I want to build an object with @Value on it, which makes all variables final, and I want to specify a default value to be used only if the user does not provide one to the builder? That's not possible.
A builder is just a fancy alternative to a constructor. It is possible to set the value of a final field in a constructor, and it is also possible to have another constructor in the same object that sets a default value for that field. I expect the same flexibility from a builder.
For example:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public Person() {
this("Bob");
}
}
Now you can get immutable Person objects:
Person p1 = new Person();
Person p2 = new Person("some other name");
But if you do this with Lombok:
@Value
@Builder
public class Person {
@Builder.Default("Bob")
private String name;
}
You cannot do this:
Person p = Person.builder().name("Some other name").build();
The name is stuck at the Builder.Default value. In that sense it is not a default, rather it is the only possible value. A default is supposed to be something that can be overridden.
I could use @Data instead of @Value but then the resulting Person objects would be mutable which I don't want.
Actually, anything involving default values seems to be very brittle and difficult to work with -- especially when deserializing objects from JSON.
The @Wither annotation results in methods that do not always make a copy, and sometimes use == instead of .equals when comparing class members. If you call one of the Wither methods and assume you have a copy of the original object, and then you modify that "copy", you might have just created a very subtle bug.
If you are using IntelliJ you can use the Refactor > Delombok menu option to show you the code that Lombok generates. I've been told that does not actually invoke the same code that the annotation processor invokes at compile time, so the results of Delombok might be misleading.