Unfortunately, Christophβs decision, as written, only works in very limited circumstances. [EDIT: as stated below, I no longer remember my reasoning for this sentence, and this is most likely incorrect: "Note that this will only work in abstract classes, first of all."] The next difficulty is that g() only works with DIRECT subclasses of A We can fix this, though:
private Class<?> extractClassFromType(Type t) throws ClassCastException { if (t instanceof Class<?>) { return (Class<?>)t; } return (Class<?>)((ParameterizedType)t).getRawType(); } public Class<B> g() throws ClassCastException { Class<?> superClass = getClass();
This will work in many situations in practice, but not ALL. Consider:
public class Foo<U,T extends Collection<?>> extends A<T> {} (new Foo<String,List<Object>>() {}).g();
This will ClassCastException because the type argument here is not at all Class or ParameterizedType ; this is TypeVariable T So now you are stuck trying to figure out what type of T was supposed to stand, and so on down the rabbit hole.
I think the only reasonable general answer is something similar to Nicholas's original answer - in general, if your class needs to create objects of some other class that is not known at compile time, users of your class need to pass this to the class (or maybe a Factory) into your class explicitly and not rely solely on generics.
Steven Collins Feb 07 2018-11-11T00: 00Z
source share