Note that there are some explanatory texts on larger screens.

plurals
  1. PORecursive generic class definition and "cannot be converted" compilation error
    primarykey
    data
    text
    <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>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload