Search code examples
javadesign-patternsbuildereffective-java

nested static builder class, further explanation on its plumbing


public class MyPojo{
    String required;
    Integer optionalOne;
    Integer optionalTwo;

    private MyPojo(Builder builder){
        this.required = builder.required
        this.optionalOne = builder.one;
        this.optionalTwo = builder.two;
    }

    public static class Builder{

        String required;
        Integer optionalOne =0;
        Integer optionalTwo =0;

        public Builder(String req){
            this.required = req;
            return this;
        }
        public Builder optionalOne(Integer one){
            this.one = one;
            return this;
        }
        public Builder optionalTwo(Integer two){
            this.two = two;
            return this;
        }
        public MyPojo build(){
            return new MyPojo(this);
        }
    }
}

Which is then called like this :

MyPojo myPojo = new MyPojo.Builder("req").optionalOne(1).optionalTwo(2).build();

Which is all lovely, but I don't understand a couple of parts.

There are two New statements one in the calling statement and one in the build() method, but there is only one new object created ?

Also, if I then call a second time , without second optional paremeter :

MyPojo myPojo = new MyPojo.Builder("req").optionalOne(1).build();

Why will optionalTwo revert back to default value (zero). And not keep the value passed in first time(2), its a static class so one instance shared between all MyPojos ?


Solution

  • This bit:

     new MyPojo().Builder("req")
    

    should be:

     new MyPojo.Builder("req")
    

    So you first create a Builder, and then the Build method (which would be better as build btw) creates the immutable object.

    If you create a second instance, that's entirely separate from the first. Don't be fooled by the Builder class being declared as static - that just means that an instance of Builder doesn't have an implicit "parent" MyPojo class reference associated with it. The fields of separate Builder instances are still entirely separate.