0
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 ?

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311

2 Answers2

3

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • well, `MyPojo.Builder()` is not declared, so there is string argument missed somewhere. If that is fixed, code is pretty straightforward. – pupssman Sep 16 '11 at 09:02
  • @pupssman there were other errors before I edited the question, e.g. the builder methods were not returning `this`. Thanks for the downvote. – Miserable Variable Sep 16 '11 at 09:05
-1

There are several errors here. As written it does not even compile.

Look up Fluent Interface for how it is supposed to work. Now consider

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

(this is not what you have, this is what you should have)

This is how it works:

  1. new MyPojo.Builder(req) creates a MyPojo.Builder object and assigns the passed req to this.required
  2. .optionOne(1) assigns 1 to MyPojo.Builder.optionalOne. It then returns the same Object (return this). This is the key, because it allows the next step
  3. .optionOne(2) assigns 2 to MyPojo.Builder.optionalTwo to the MyPojo.Builder object returned by the previous call. Note that we are still working with the same Builder object created in step 1. this is returned again
  4. Build() calls Build method on the Builder, which in turn calls the MyPojo constructor. This method should be called build to conform to Java naming conventions.

EDIT: The code is not compilable. EDIT2: Detailed explanation

Miserable Variable
  • 28,432
  • 15
  • 72
  • 133