Note that there are some explanatory texts on larger screens.

plurals
  1. POGeneric Restriction Hell: Bound Mismatch
    primarykey
    data
    text
    <p>I'm working on a project that has an extensive tree of generic inheritance and dependencies. Go to edit to see better example. <strike>The basics look something like this:</p> <pre><code>class A { ... } class B { ... } class C extends B { ... } class D&lt;T extends B&gt; extends A { ... } class StringMap&lt;T extends A&gt; { HashMap&lt;String, T&gt; _elements; ... } </code></pre> <p>So now I'm going to write a class that contains a specific <code>StringMap</code> type.</p> <pre><code>class X { StringMap&lt;D&lt;C&gt;&gt; _thing = new StringMap&lt;D&lt;C&gt;&gt;; ... } </code></pre> <p>So far this all works fine. <code>D&lt;C&gt;</code> is actually a very long name and the specific combination is going to show up very frequently in other parts of the code, so I decided to a class for the specific combination so it will be clearer and have a shorter name.</p> <pre><code>class DC extends D&lt;C&gt; { } //and go to update X class X { StringMap&lt;D&lt;C&gt;&gt; _thing = new StringMap&lt;D&lt;C&gt;&gt;(); //still works fine StringMap&lt;DC&gt; _thing = new StringMap&lt;DC&gt;(); //error ... } </code></pre> <p></strike></p> <p>Eclipse gives the error of</p> <blockquote> <p>Bound mismatch: The type <code>DC</code> is not a valid substitute for the bounded parameter <code>&lt;T extends A&gt;</code> of the type <code>StringMap&lt;T&gt;</code></p> </blockquote> <p>So the question is, why does this not just work? <code>DC</code> does nothing but extend <code>D&lt;C&gt;</code> and echo the constructors. Why does <code>StringMap</code> see <code>DC</code> as different when it is just a child class of something it excepts?</p> <p><strong>EDIT:</strong><br> OK, reworked the example to be closer to what I'm actually doing. I tested it and it does produce the error. What I'm doing here is using the generic type to ensure that <code>clone()</code> returns the correct class for whoever implements it down the inheritance tree. Then in subclasses, I'm using <code>B&lt;T extends B&lt;T&gt;&gt;</code> to ensure that subclasses of <code>B</code> are passing in a subclass of B as the generic type <code>T</code>.</p> <pre><code>public abstract class Undoable&lt;T&gt; implements Comparable&lt;T&gt; { public abstract T clone(); public abstract void updateFields(T modified); } abstract public class A&lt;T extends A&lt;T, U&gt;, U extends Comparable&lt;U&gt;&gt; extends Undoable&lt;T&gt; { abstract U getKey(); @Override public int compareTo(T element) { return getKey().compareTo(element.getKey()); } } public class B&lt;T extends B&lt;T&gt;&gt; extends A&lt;T, String&gt; { @Override public T clone() { // TODO Auto-generated method stub return null; } @Override public void updateFields(T modified) { // TODO Auto-generated method stub } @Override String getKey() { // TODO Auto-generated method stub return null; } } public class C extends B&lt;C&gt; { } public class D&lt;T extends B&lt;T&gt;&gt; extends A&lt;D&lt;T&gt;, String&gt; { @Override String getKey() { // TODO Auto-generated method stub return null; } @Override public D&lt;T&gt; clone() { // TODO Auto-generated method stub return null; } @Override public void updateFields(D&lt;T&gt; modified) { // TODO Auto-generated method stub } } public class DC extends D&lt;C&gt; { } public class StringMap&lt;T extends Undoable&lt;T&gt;&gt; { HashMap&lt;String, T&gt; _elements; } public class Main { public static void main(String[] args) { StringMap&lt;D&lt;C&gt;&gt; _thing = new StringMap&lt;D&lt;C&gt;&gt;(); //works StringMap&lt;DC&gt; _thing1 = new StringMap&lt;DC&gt;(); //error //Bound mismatch: The type DC is not a valid substitute for //the bounded parameter &lt;T extends Undoable&lt;T&gt;&gt; of the type StringMap&lt;T&gt; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    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.
 

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