Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Unfortunately Christoph's solution as written only works in very limited circumstances. [EDIT: as commented below I no longer remember my reasoning for this sentence and it is likely wrong: "Note that this will only work in abstract classes, first of all."] The next difficulty is that <code>g()</code> only works from DIRECT subclasses of <code>A</code>. We can fix that, though:</p> <pre><code>private Class&lt;?&gt; extractClassFromType(Type t) throws ClassCastException { if (t instanceof Class&lt;?&gt;) { return (Class&lt;?&gt;)t; } return (Class&lt;?&gt;)((ParameterizedType)t).getRawType(); } public Class&lt;B&gt; g() throws ClassCastException { Class&lt;?&gt; superClass = getClass(); // initial value Type superType; do { superType = superClass.getGenericSuperclass(); superClass = extractClassFromType(superType); } while (! (superClass.equals(A.class))); Type actualArg = ((ParameterizedType)superType).getActualTypeArguments()[0]; return (Class&lt;B&gt;)extractClassFromType(actualArg); } </code></pre> <p>This will work in many situations in practice, but not ALL the time. Consider:</p> <pre><code>public class Foo&lt;U,T extends Collection&lt;?&gt;&gt; extends A&lt;T&gt; {} (new Foo&lt;String,List&lt;Object&gt;&gt;() {}).g(); </code></pre> <p>This will throw a <code>ClassCastException</code>, because the type argument here isn't a <code>Class</code> or a <code>ParameterizedType</code> at all; it's the <code>TypeVariable</code> <code>T</code>. So now you would be stuck trying to figure out what type <code>T</code> was supposed to stand for, and so on down the rabbit hole.</p> <p>I think the only reasonable, general answer is something akin to Nicolas's initial answer -- in general, if your class needs to instantiate objects of some other class that is unknown at compile-time, users of your class need to pass that class literal (or, perhaps, a Factory) to your class explicitly and not rely solely on generics.</p>
 

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