title: Recursive generic class definition and "cannot be converted" compilation error
body: <p>This is a design similar to other JPA BaseEntity patterns you may have seen:</p>
  
  <pre><code>@MappedSuperclass()
  public abstract class Entity&lt;X extends Entity&lt;X&gt;&gt;
      implements
          Comparable&lt;X&gt;,
          Serializable
  {
      private static final long serialVersionUID = 1L;
      private Long id;
      private Date timeStamp;
  
  ...
  
      //  Simply compare fields in subclass until difference is discovered
      private int compareSubclassFields(X that)
      {
          int result = 0;
          for(Comparator&lt;X&gt; comparator : getComparators())
          {
              result = comparator.compare(this,that); &lt;&lt;=== compilation error
              if(result != 0) { break; }
          }
          return result;
      }
  
      /**
       *  Entity subclasses provide a list of their own special
       *  comparators that can contribute to the comparison.
       */
      protected abstract List&lt;Comparator&lt;X&gt;&gt; getComparators();
  }
  </code></pre>
  
  <p>Here is an example of a class that extends Entity:</p>
  
  <pre><code>public class User extends Entity&lt;User&gt;
  {
      private static final long serialVersionUID = 1L;
      private String firstName;
      private String lastName;
      private String email;
  
  ...
  
      @Override
      public List&lt;Comparator&lt;User&gt;&gt; getComparators()
      {
          List&lt;Comparator&lt;User&gt;&gt; result =
              new ArrayList&lt;Comparator&lt;User&gt;&gt;();
  
          result.add(getLastNameComparator()); //  Sort first on last name
          result.add(getFirstNameComparator());//  Next, by first name
          result.add(getEmailComparator());    //  Finally, by email (unique)
          return result;
      }
  }
  </code></pre>
  
  <p>When I compile, I get the following error:</p>
  
  <pre><code>error: method compare in interface Comparator&lt;T&gt; cannot be 
         applied to given types;
  
          result = comparator.compare(this,that);
                                      ^
  required: X,X
  found: Entity&lt;X&gt;,X
  reason: actual argument Entity&lt;X&gt; cannot be converted to
          X by method invocation conversion
  
  where X,T are type-variables:
    X extends Entity&lt;X&gt; declared in class Entity
    T extends Object declared in interface Comparator
  </code></pre>
  
  <p>Reading <a href="https://stackoverflow.com/questions/211143/java-enum-definition">Java Enum Definition</a>, in particular the part where it says,</p>
  
  <pre><code>public class StatusCode extends Enum&lt;StatusCode&gt;
  </code></pre>
  
  <blockquote>
    <p>Now if you check the constraints, we've got Enum - so E=StatusCode. Let's check: does E extend Enum? Yes! We're okay.  </p>
  </blockquote>
  
  <p>I assume that in my example, where <code>X extends Entity&lt;X&gt;</code>, 'this' would be an instance of <code>User</code> and not <code>Entity&lt;User&gt;</code>.  Moreover, because Entity is an abstract class it <em>must</em> be extended and, therefore, <code>compareNonIdFields</code> can only be invoked by an instance of X -- on itself.  Of course, when I cast I get the unchecked warning:</p>
  
  <pre><code>warning: [unchecked] unchecked cast
          result = comparator.compare(((X)this),that);
                                          ^
  required: X
  found:    Entity&lt;X&gt;
  where X is a type-variable:
    X extends Entity&lt;X&gt; declared in class Entity
  1 warning
  </code></pre>
  
  <p>Thoughts on why this recursive generic usage causes a compilation error and solutions to make the unchecked cast warning go away would be greatly appreciated.</p>