 <p>I was just pointed to this solution:</p> <pre><code>import java.lang.reflect.ParameterizedType; public abstract class A&lt;B&gt; { public Class&lt;B&gt; g() throws Exception { ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass(); return (Class&lt;B&gt;) superclass.getActualTypeArguments()[0]; } } </code></pre> <p>This works if <code>A</code> is given a concrete type by a subclass:</p> <pre><code>new A&lt;String&gt;() {}.g() // this will work class B extends A&lt;String&gt; {} new B().g() // this will work class C&lt;T&gt; extends A&lt;T&gt; {} new C&lt;String&gt;().g() // this will NOT work </code></pre>