Note that there are some explanatory texts on larger screens.

plurals
  1. POJava generics vs. Factory
    primarykey
    data
    text
    <h2>Setup:</h2> <p>I have an interface for some formatters:</p> <pre><code>interface Formatter&lt;T extends AbstractItem&gt; { String format(T item); } </code></pre> <p>I have a factory creating such formatters:</p> <pre><code>public class Factory { public static Formatter&lt;? extends AbstractItem&gt; create() { switch (something) { case SOMETHING: return new Formatter&lt;SomeItem&gt;() { String format(SomeItem item) {...}}; case SOMETHING_ELSE: return new Formatter&lt;OtherItem&gt;() { String format(OtherItem item){...}}; } </code></pre> <p>Now I use this factory to obtain the formatter &amp; I use it:</p> <pre><code>1: Formatter formatter = Factory.create(); 2: for (AbstractItem item : items) { 3: formatter.format(item); 4: } </code></pre> <p>The <code>items</code> list contains only <code>AbstractItem</code> subtypes that the <code>formatter</code> is able to process.</p> <h2>Problem:</h2> <p>I am getting two warnings:</p> <pre><code>Line 1: Formatter is a raw type. References to generic type Formatter&lt;T&gt; should be parameterized. Line 3: Type safety: The method format(AbstractItem) belongs to the raw type Formatter. References to generic type Formatter&lt;T&gt; should be parameterized. </code></pre> <p>OK, so I try to fix the first one: I know that the factory returns something descended from <code>AbstractItem</code>:</p> <pre><code>1: Formatter&lt;? extends AbstractItem&gt; formatter = Factory.create(); </code></pre> <p>Now the warning on Line 1 disappears, but a new error on Line 3 occurs:</p> <pre><code>Line 3: The method format(capture#3-of ? extends AbstractItem) in the type Formatter&lt;capture#3-of ? extends AbstractItem&gt; is not applicable for the arguments (AbstractItem). </code></pre> <p>So if I understand correctly, it's complaining that <code>AbstractItem</code> is not a sub-type of <code>AbstractItem</code> (as required in the type constraint <code>&lt;? extends AbstractItem&gt;</code>). Fair enough, but <code>AbstractItem</code> is abstract, so the <code>item</code> I pass to the <code>formatter</code> is always of some type extending <code>AbstractItem</code>...</p> <p>How do I explain this to the compiler? For now my solution is to go with the <code>@SuppressWarnings</code>...</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.
 

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