1
public static class Builder<T extends Builder<T>> {

    private int calories = 0;

    public Builder() {}

    public T calories(int val) {
        calories = val;
        return (T) this;
    }

    public NutritionFacts build() { return new NutritionFacts(this); }
}

From this code snippet, what does the first line do, public static class Builder<T extends Builder<T>>? Is there a recursion here?

Henok Tesfaye
  • 8,287
  • 13
  • 47
  • 84

1 Answers1

2

This simply means that the type of T must be a class that extends Builder. See this example:

public class ABuilder extends Builder<ABuilder> {

}

This construct is commonly seen when using the builder pattern, because it allows a super class to return an instance of the subclass so that subclass methods may still be used. From the example you've shown:

public T calories(int val) {
    calories = val;
    return (T) this;
}

Will allow that this code snippet works:

NutritionFacts nf = new ABuilder()
    .specificMethodForABuilder()        // returns ABuilder
    .calories(3)                        // returns also ABuilder
    .anotherSpecificMethodForABuilder() // returns again ABuilder
    .build();

The same would not work if the calories() method would've been declared like this (and the builder without a generic T):

public Builder calories(int val) {
    calories = val;
    return this;
}

You would get a compilation error if you tried this:

NutritionFacts nf = new ABuilder()
    .specificMethodForABuilder()        // returns ABuilder
    .calories(3)                        // returns only Builder
    .anotherSpecificMethodForABuilder() // unknown method
    .build();
Lino
  • 19,604
  • 6
  • 47
  • 65
  • `(T) this` is not type safe. The recursive bound does not help with this. The recursive bound is useful for other things. – newacct Apr 11 '19 at 04:58