В рамках моего кода следующего абстрактного суперкласса
public abstract class AbstractClass<Type extends A> {...}
и некоторые дочерние классы как
public class ChildClassA extends AbstractClass<GenericTypeA> {...}
public class ChildClassB extends AbstractClass<GenericTypeB> {...}
Я ищу изящный путь, как я могу использовать универсальный тип дочерних классов (GenericTypeA, GenericTypeB...) в абстрактном классе универсальным способом.
Для решения этой проблемы, я в настоящее время определял метод
protected abstract Class<Type> getGenericTypeClass();
в моем абстрактном классе и реализованный метод
@Override
protected Class<GenericType> getGenericTypeClass() {
return GenericType.class;
}
в каждом дочернем классе.
Действительно ли возможно получить универсальный тип дочерних классов в моем абстрактном классе, не реализовывая этот вспомогательный метод?
BR,
Markus
Я думаю, это возможно. Я видел, что это используется в паттернах DAO вместе с дженериками. Например. Рассмотрим классы:
public class A {}
public class B extends A {}
И ваш родовой класс:
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);
}
}
У вас может быть класс Test1, который расширяет Test с помощью класса B (он расширяет 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'
}
}
Я не уверен, что полностью понимаю ваш вопрос -
- это общий тип подкласса, даже если он выражен в абстрактном классе. Например, если ваш абстрактный суперкласс определяет метод:
public void augment(Type entity) {
...
}
и вы создаете экземпляр ChildClassA
, вы сможете вызвать augment
только с экземпляром GenericTypeA
.
Теперь, если вам нужен литерал класса, вам нужно предоставить метод, как вы указали. Но если вам просто нужен общий параметр, вам не нужно делать ничего особенного.