Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

IIRC @Builder.Default only makes them immutable if you also specify that the variable is final.


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.


Can't you just use @Data and @Setter(AccessLevel.NONE)? That's effectively the same as using final but without the keyword.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: