JAVA - 获取 class 的通用实现
JAVA - Get generic implementation of a class
假设我有一个抽象 class 定义 Generic Type
。所有子classes 都将实现此通用类型。
我可以通过声明一个强制 subclass 到 return 该类型的抽象方法来实现。但是有没有更优雅的方法可以直接从 subclass 的 '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;}
}
提前致谢
您可以将抽象方法的 return 类型设置为 Class
,使用通用类型进行参数化:
abstract class AbsClazz<T> {
abstract Class<T> getGenericType();
}
然后,在你的子class中,你将被迫实现一个方法,returns [=]中提供的类型19=]定义。例如:
class ClazzImplString extends AbsClazz<String> {
public ClazzImplString() {}
@Override Class<String> getGenericType() {return String.class;}
}
是的,您可以使用 reflection。
ParameterizedType genericSuperclass = (ParameterizedType) ClazzImplString.class.getGenericSuperclass();
Class<?> clazz = (Class<?>) genericSuperclass.getActualTypeArguments()[0];
System.out.println(clazz); // prints class java.lang.String
这是一个疯狂的反射技巧:
import java.lang.reflect.ParameterizedType;
class GenericClazz<T> {
public Class<T> getType() {
return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}
(来源 - 我的旧项目之一:link)
您可以避免每个子类型上的 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
假设我有一个抽象 class 定义 Generic Type
。所有子classes 都将实现此通用类型。
我可以通过声明一个强制 subclass 到 return 该类型的抽象方法来实现。但是有没有更优雅的方法可以直接从 subclass 的 '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;}
}
提前致谢
您可以将抽象方法的 return 类型设置为 Class
,使用通用类型进行参数化:
abstract class AbsClazz<T> {
abstract Class<T> getGenericType();
}
然后,在你的子class中,你将被迫实现一个方法,returns [=]中提供的类型19=]定义。例如:
class ClazzImplString extends AbsClazz<String> {
public ClazzImplString() {}
@Override Class<String> getGenericType() {return String.class;}
}
是的,您可以使用 reflection。
ParameterizedType genericSuperclass = (ParameterizedType) ClazzImplString.class.getGenericSuperclass();
Class<?> clazz = (Class<?>) genericSuperclass.getActualTypeArguments()[0];
System.out.println(clazz); // prints class java.lang.String
这是一个疯狂的反射技巧:
import java.lang.reflect.ParameterizedType;
class GenericClazz<T> {
public Class<T> getType() {
return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}
(来源 - 我的旧项目之一:link)
您可以避免每个子类型上的 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