想象一下,我有一个定义Generic Type
的抽象类。所有子类都将实现此通用类型。
我可以通过声明一个强制子类返回该类型的抽象方法来实现。但有没有更优雅的方法直接从子类的'Class'对象定义实现这一点?
public class GenericTest {
public static void main(String[]args) throws Exception{
Class strClass = ClazzImplString.class;
Class intClass = ClazzImplInteger.class;
Class implTypeStr = ((AbsClazz)strClass.getConstructor().newInstance()).getGenericType();
Class implTypeInt = ((AbsClazz)intClass.getConstructor().newInstance()).getGenericType();
System.out.println("implTypeStr: " + implTypeStr);
System.out.println("implTypeInt: " + implTypeInt);
}
}
abstract class AbsClazz<GenericType> {
abstract Class getGenericType();
}
class ClazzImplString extends AbsClazz<String> {
public ClazzImplString() {}
@Override Class getGenericType() {return String.class;}
}
class ClazzImplInteger extends AbsClazz<Integer> {
public ClazzImplInteger() {}
@Override Class getGenericType() {return Integer.class;}
}
提前谢谢
答案 0 :(得分:5)
您可以将抽象方法的返回类型设置为Class
,使用泛型类型进行参数化:
abstract class AbsClazz<T> {
abstract Class<T> getGenericType();
}
然后,在您的子类中,您将强制实现一个方法,该方法返回类定义中提供的类型。例如:
class ClazzImplString extends AbsClazz<String> {
public ClazzImplString() {}
@Override Class<String> getGenericType() {return String.class;}
}
答案 1 :(得分:5)
是的,您可以使用reflection。
ParameterizedType genericSuperclass = (ParameterizedType) ClazzImplString.class.getGenericSuperclass();
Class<?> clazz = (Class<?>) genericSuperclass.getActualTypeArguments()[0];
System.out.println(clazz); // prints class java.lang.String
答案 2 :(得分:2)
这是一个反思的疯狂黑客:
import java.lang.reflect.ParameterizedType;
class GenericClazz<T> {
public Class<T> getType() {
return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}
(来源 - 我的一个旧项目:link)
答案 3 :(得分:1)
您可以避免每个子类型的getGenericType
从子类型获得ParameterizedType
。
示例如下:
public abstract class AbsClazz<E extends Serializable> { }
public class ClazzImplInteger extends AbsClazz<Integer> { }
public class ClazzImplString extends AbsClazz<String> { }
public class GenericTest {
public static void main(String[] args) {
System.out.println("implTypeStr: " + getTypeFromGenericClass(ClazzImplString.class, 0));
System.out.println("implTypeInt: " + getTypeFromGenericClass(ClazzImplInteger.class, 0));
}
public static Class<?> getTypeFromGenericClass(final Class<?> genericType, final Integer index) {
final ParameterizedType type = (ParameterizedType) genericType.getGenericSuperclass();
return (Class<?>) type.getActualTypeArguments()[index];
}
}
此示例将打印:
implTypeStr: class java.lang.String
implTypeInt: class java.lang.Integer