Within my code a have the following abstract superclass
public abstract class AbstractClass<Type extends A> {...}
and some child classes like
public class ChildClassA extends AbstractClass<GenericTypeA> {...}
public class ChildClassB extends AbstractClass<GenericTypeB> {...}
I'm searching for an elegant way how I can use the generic type of the child classes (GenericTypeA, GenericTypeB, ...) inside the abstract class in a generic way.
To solve this problem I currently defined the method
protected abstract Class<Type> getGenericTypeClass();
in my abstract class and implemented the method
@Override
protected Class<GenericType> getGenericTypeClass() {
return GenericType.class;
}
in every child class.
Is it possible to get the generic type of the child classes in my abstract class without implementing this helper method?
BR,
Markus
I think its possible. I saw this was being used in the DAO patterns along with generics. e.g.
Consider classes:
public class A {}
public class B extends A {}
And your generic class:
import java.lang.reflect.ParameterizedType;
public abstract class Test<T extends A> {
private Class<T> theType;
public Test() {
theType = (Class<T>) (
(ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
// this method will always return the type that extends class "A"
public Class<T> getTheType() {
return theType;
}
public void printType() {
Class<T> clazz = getTheType();
System.out.println(clazz);
}
}
You can have a class Test1 that extends Test with class B (it extends A)
public class Test1 extends Test<B> {
public static void main(String[] args) {
Test1 t = new Test1();
Class<B> clazz = t.getTheType();
System.out.println(clazz); // will print 'class B'
System.out.println(printType()); // will print 'class B'
}
}
I'm not sure I fully understand your question - <Type>
is the generic type of the subclass, even when it's being expressed in the abstract class. For example, if your abstract superclass defines a method:
public void augment(Type entity) {
...
}
and you instantiate a ChildClassA
, you'll only be able to call augment
with an instance of GenericTypeA
.
Now if you want a class literal, then you'll need to provide the method as you indicated. But if you just want the generic parameter, you don't need to do anything special.