Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling multiple methods in Java

I found a new way of calling multiple methods in Java and I don't really understands what's happening behind:

public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;

public static class Builder {
    // Required parameters
    private final int servingSize;
    private final int servings;
    // Optional parameters - initialized to default values
    private int calories      = 0;
    private int fat           = 0;
    private int carbohydrate  = 0;
    private int sodium        = 0;
    public Builder(int servingSize, int servings) {
        this.servingSize = servingSize;
        this.servings    = servings;
    }
        public Builder calories(int val)
            { calories = val;      return this; }
        public Builder fat(int val)
            { fat = val;           return this; }
        public Builder carbohydrate(int val)
            { carbohydrate = val;  return this; }
        public Builder sodium(int val)
            { sodium = val;        return this; }
        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
}  

    private NutritionFacts(Builder builder) {
        servingSize  = builder.servingSize;
        servings     = builder.servings;
        calories     = builder.calories;
    }

}

Now the class is instantiated using this line, and here's where it gets confusing:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();

It all makes sense till the NutritionFacts.Build(int, int), after that, what exactly is happening? Why do the calories, sodium, carbohydrate methods from Builder class need to return this? Where does that class adress go into?

Thank you!

like image 610
Mihai Neacsu Avatar asked Oct 26 '11 23:10

Mihai Neacsu


2 Answers

It doesn't "go into" anything.

These methods return a value. In this case, they return the current instance, this. That instance has methods, like calories() and carbohydrates().

foo.calories(12) returns the instance, and we can call its methods: foo.calories(12).sodium(35).

It's no different than the "return value" from the constructor, implicitly defined as the new instance. In this case it's normal methods, still returning an instance--the current one.

It's the same as this:

Builder foo = new Builder(1, 2); // The "return" value of a ctor is the reference, foo
foo.sodium(10);   // Returns foo, but we ignore it
foo.calories(42); // Returns foo, but we ignore it

(foo.sodium(10)).calories(42);
^^^^^^^^^^^^^^^^ foo, with the side effect of setting the sodium value

Here's an SO question with some good examples.

like image 166
Dave Newton Avatar answered Oct 16 '22 05:10

Dave Newton


This is generally known as method chaining and it is a pretty common idea across OO:

http://en.wikipedia.org/wiki/Method_chaining

like image 23
Jere Avatar answered Oct 16 '22 06:10

Jere