title: Java Abstract, Generics, and Builders
body: <p>this is my first time posting but I'm having a lot of trouble with a problem.
  I currently have an AbstractDevice class with the header:</p>
  
  <pre><code>public abstract class AbstractDevice&lt;T extends AbstractDevice.Builder&lt;T&gt;&gt; implements Device
  </code></pre>
  
  <p>and this class has a nested builder class with the header:</p>
  
  <pre><code>public static abstract class Builder&lt;T&gt;
  </code></pre>
  
  <p>I also have a AbstractPeripheral class with the header:</p>
  
  <pre><code>public abstract class  AbstractPeripheral&lt;T extends AbstractPeripheral.Builder&lt;T&gt;&gt; extends AbstractDevice&lt;AbstractPeripheral.Builder&gt;
  </code></pre>
  
  <p>and this class also has its own nested builder class with the header: </p>
  
  <pre><code>public static abstract class Builder&lt;T&gt; extends AbstractDevice.Builder&lt;Builder&gt;.
  </code></pre>
  
  <p>My goal is the have the AbstractPeripheral extend the AbstractDevice and the AbstractPeripheral's builder extend AbstractDevice's. However, I am getting this error when trying to compile:</p>
  
  <blockquote>
    <p>type argument uxb.AbstractPeripheral.Builder is not within bounds of type-variable T.</p>
  </blockquote>
  
  <p>Any help is appreciated. Thanks
  Abstract Device:</p>
  
  <pre><code>package uxb;
  
  import java.util.List;
  import java.util.Optional;
  import java.util.ArrayList;
  import java.math.BigInteger;
  
  
  public abstract class AbstractDevice&lt;T extends AbstractDevice.Builder&lt;T&gt;&gt;     
  implements Device{
  
  public static abstract class Builder&lt;T&gt;{
  
  private Integer version;
  
  private Optional&lt;Integer&gt; productCode;
  
  private Optional&lt;BigInteger&gt; serialNumber;
  
  private List&lt;Connector.Type&gt; connectors;
  
  public Builder(Integer version){
    this.version = version;
  }  //end constructor method
  
  
  public T productCode(Integer productCode){
    if(productCode != null){
      this.productCode = Optional.of(productCode); 
    }  //end if statement
    else{
      this.productCode = Optional.empty();
    }  //end else statement
    return getThis();
  }  //end method productCode()
  
  public T serialNumber(BigInteger serialNumber){
    if(serialNumber != null){
      this.serialNumber = Optional.of(serialNumber);
    }  //end if statement
    else{
    /*Class has a static field for ZERO value*/
      this.serialNumber = Optional.empty();
    }  //end else statement
    return getThis();
  }  //end method serialNumber()
  
  
  public T connectors(List&lt;Connector.Type&gt; connectors){
   this.connectors = connectors;
   return getThis();
  }  //end method connectors
  
  
  protected abstract T getThis();
  
  
  protected List&lt;Connector.Type&gt; getConnectors(){
    return connectors;
  }  //end method getConnectors()
  
  
  protected void validate(){
    if(version == null){
      throw new NullPointerException("Cannot be validated");
    }
  }  //end method validate()
  
  }  //end nested abstract class Builder
  
  
  private final Integer version;
  
  private final Optional&lt;Integer&gt; productCode;
  
  
  private final Optional&lt;BigInteger&gt; serialNumber;
  
  private final List&lt;Connector.Type&gt; connectors;
  
  private final List&lt;Connector&gt; connectorObjects;
  
  
  protected AbstractDevice(Builder&lt;T&gt; builder){
    this.version = builder.version;
    this.productCode = builder.productCode;
    this.serialNumber = builder.serialNumber;
    this.connectors = builder.connectors;
    ArrayList&lt;Connector&gt; temp = new ArrayList&lt;Connector&gt;();
    for(int i = 0; i &lt; connectors.size(); i++){
      temp.add(new Connector(this, i, connectors.get(i)));
    }  //end for loop
    connectorObjects = temp;
  }  //end constructor method
  
  
  
  public Optional&lt;Integer&gt; getProductCode(){
  return productCode;
  }  //end method getProductCode()
  
  
  public Integer getConnectorCount(){
  /*Not Implemented Yet*/
  return 0;
  }  //end method getConnectorCount()
  
  
  
  public Optional&lt;BigInteger&gt; getSerialNumber(){
  return serialNumber;
  }  //end method getSerialNumber()
  
  
  public Integer getVersion(){
  return version;
  }  //end method getVersion()
  
  public List&lt;Connector&gt; getConnectors(){
  return new ArrayList&lt;Connector&gt;(connectorObjects);
  }  //end method getConnectors()
  
  
  public Connector getConnector(int index){
    if(! getConnectors().isEmpty()){
    return getConnectors().get(index);
  }  //end if statement
  else{
    return null;
  }  //end else statement
  }  //end method getConnector()
  
  } //end abstract class AbstractDevice
  </code></pre>
  
  <p>Abstract Peripheral:
      package uxb;</p>
  
  <pre><code>import java.util.List;
  
  public abstract class  AbstractPeripheral&lt;T extends  
  AbstractPeripheral.Builder&lt;T&gt;&gt; extends 
  AbstractDevice&lt;AbstractPeripheral.Builder&gt;{
  
  public static abstract class Builder&lt;T&gt; extends 
  AbstractDevice.Builder&lt;Builder&gt;{
  
  protected void validate(){
    super.validate();
    if(getConnectors().equals(null)){
      throw new IllegalStateException("Cannot be validated");
    }  //end if statement
    if(checkTypes(getConnectors())){
      throw new IllegalStateException("Cannot be validated");
    }  //end if statement
  }  //end method 
  
  private boolean checkTypes(List&lt;Connector.Type&gt; types){
    for(Connector.Type type: types){
      if(type != Connector.Type.PERIPHERAL){
        return false;
      }  //end if statement
    }  //end for each loop
    return true;
  }  //end method checkTypes
  
  public Builder(Integer version){
    super(version);
  }  //end constructor method
  }  //end nested class Builder
  
  public AbstractPeripheral(Builder&lt;T&gt; builder){
   super(builder);
  } 
  }  //end class AbstractPeripheral
  </code></pre>
  
  <p>Hub:
      package uxb;</p>
  
  <pre><code>public class Hub extends AbstractDevice&lt;Hub.Builder&gt;{
  
    public static class Builder extends AbstractDevice.Builder&lt;Builder&gt;{
  
  public Builder(Integer version){
    super(version);
  } //end constructor method
  
  public Hub build(){
   validate();
   return new Hub(getThis());
  }  //end method build()
  
  protected Builder getThis(){
    return this;
  } //end method getThis()
  
  protected void validate(){
    super.validate();
    if(!(super.getConnectors().contains(Connector.Type.COMPUTER))){
      throw new IllegalStateException("Cannot be validated");
    }  //end if statement\
    if(!(super.getConnectors().contains(Connector.Type.PERIPHERAL))){
      throw new IllegalStateException("Cannot be validated");
    }  //end if statement
  }  //end validate()
  }  //end nested class Builder
  
  private Hub(Builder builder){
  super(builder);
  }  //end constructor method
  
  public DeviceClass getDeviceClass(){
  return DeviceClass.HUB;
  }  //end method getDeviceClass()
  
  
  }  //end class Hub
  </code></pre>