title: how generic type with a recursive type parameter along with the abstract self method allows method chaining to work properly?
body: <p>I am reading <strong>Effective Java Edition 3</strong>. in chapter 2 page 14, the author talks about the builder pattern and presents this code:</p>
  <pre><code>public abstract class Pizza {
      public enum Topping { HAM, MUSHROOM, ONION, PEPPER, SAUSAGE }
      final Set&lt;Topping&gt; toppings;
      abstract static class Builder&lt;T extends Builder&lt;T&gt;&gt; {
          EnumSet&lt;Topping&gt; toppings = EnumSet.noneOf(Topping.class);
          public T addTopping(Topping topping) {
              toppings.add(Objects.requireNonNull(topping));
              return self();
          }
          abstract Pizza build();
          // Subclasses must override this method to return &quot;this&quot;
          protected abstract T self();
      }
      Pizza(Builder&lt;?&gt; builder) {
          toppings = builder.toppings.clone(); // See Item 50
      }
  }
  </code></pre>
  <p>an implementation of above abstract class:</p>
  <pre><code>public class NyPizza extends Pizza {
      public enum Size { SMALL, MEDIUM, LARGE }
      private final Size size;
      public static class Builder extends Pizza.Builder&lt;Builder&gt; {
          private final Size size;
          public Builder(Size size) {
              this.size = Objects.requireNonNull(size);
          }
          @Override public NyPizza build() {
              return new NyPizza(this);
          }
          @Override protected Builder self() { return this; }
      }
      private NyPizza(Builder builder) {
          super(builder);
          size = builder.size;
      }
  }
  </code></pre>
  <p>and we can use code like this:</p>
  <pre><code>NyPizza pizza = new NyPizza.Builder(SMALL)
  .addTopping(SAUSAGE).addTopping(ONION).build();
  </code></pre>
  <p>quote from the book:</p>
  <blockquote>
  <p>Note that <code>Pizza.Builder</code> is a <em>generic type</em> with <em>recursive type
  parameter</em>. this, along with the abstract self method, allows method
  chaining to work properly in subclasses, without the need for casts.</p>
  </blockquote>
  <p>now my question is what power/value <code>&lt;T extends Builder&lt;T&gt;&gt;</code> added to <code>Pizza</code> class and how it is different with <code>&lt;T extends Builder&gt;</code>?  if you are going to explain <code>&lt;T extends Builder&lt;T&gt;&gt;</code> to a five years old kid in simple English how would you explain it?</p>
  <p>and I can't figure out the purpose of abstract self method in the super class?</p>
  <hr />
  <p><strong>I add this part because of the comment section</strong></p>
  <p>Imagine I have changed the above codes like this(it is not going to be the best example just for illustration purposes):</p>
  <p>I changed the <code>NyPizza.Builder</code> to be generic:</p>
  <pre><code>public class NyPizza extends Pizza {
      public enum Size { SMALL, MEDIUM, LARGE }
      private final Size size;
      public static class Builder&lt;T&gt; extends Pizza.Builder&lt;Builder&lt;T&gt;&gt; {
          private final Size size;
          public Builder(Size size) {
              this.size = Objects.requireNonNull(size);
          }
          @Override public NyPizza build() {
              return new NyPizza(this);
          }
          @Override protected Builder self() { return this; }
      }
      private NyPizza(Builder builder) {
          super(builder);
          size = builder.size;
      }
  }
  </code></pre>
  <p>and the <code>Pizza</code> class like this:</p>
  <pre><code>public abstract class Pizza {
      public enum Topping { HAM, MUSHROOM, ONION, PEPPER, SAUSAGE }
      final Set&lt;Topping&gt; toppings;
      abstract static class Builder&lt;T extends Builder&gt; {
          T obj;
          EnumSet&lt;Topping&gt; toppings = EnumSet.noneOf(Topping.class);
          public T addTopping(Topping topping) {
              toppings.add(Objects.requireNonNull(topping));
              return self();
          }
  
          public T builder(){
              return obj;
          }
  
          abstract Pizza build();
          // Subclasses must override this method to return &quot;this&quot;
          protected abstract T self();
      }
      Pizza(Builder&lt;?&gt; builder) {
          toppings = builder.toppings.clone(); // See Item 50
      }
  }
  </code></pre>
  <p>and used the above classes like this:</p>
  <p><code>NyPizza.Builder&lt;String&gt; test = new NyPizza.Builder&lt;String&gt;(SMALL).builder();</code></p>
  <p>now because I didn't define <code>class Builder&lt;T extends Builder&gt;</code> in this form: <code>class Builder&lt;T extends Builder&lt;T&gt;&gt;</code> the <code>builder</code> method in the <code>Pizza</code> class should not be able to detect the type of the T is <code>NyPizza.Builder&lt;String&gt;</code> but it can. how is it possible? how change it to <strong>need casting</strong>?</p>