Skip to content

Instantly share code, notes, and snippets.

@OlivierCroisier
Created December 18, 2024 21:10
Show Gist options
  • Save OlivierCroisier/69bc7bcde65e1012339f7b4d43c11724 to your computer and use it in GitHub Desktop.
Save OlivierCroisier/69bc7bcde65e1012339f7b4d43c11724 to your computer and use it in GitHub Desktop.
package foo;
import java.util.function.Consumer;
public class Foo {
public static void main(String[] args) {
Foo foo = new Foo($ -> $
.firstName("John")
.lastName("Doe")
.age(42)
);
System.out.println(foo.getFirstName());
// Will throw an exception (see Builder's constructor below)
// Foo foo2 = new Foo();
// Foo.Builder builder2 = foo2.new Builder();
// builder2.age(10);
}
// ------------------------------------------------------------------------------------------
private String firstName;
private String lastName;
private int age;
public Foo() {
}
public Foo(Consumer<Builder> builder) {
builder.accept(new Builder());
}
// Look ma, no setters here !
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public class Builder {
public Builder() {
// Builder Will throw an exception if called outside Foo's constructor (optional but cleaner IMHO)
Class<?> caller = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass();
if (caller != Foo.class) {
throw new IllegalStateException("Cannot call builder outside the constructor");
}
}
public Builder firstName(String firstName) {
Foo.this.firstName = firstName;
return this;
}
public Builder lastName(String lastName) {
Foo.this.lastName = lastName;
return this;
}
public Builder age(int age) {
Foo.this.age = age;
return this;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment