在Java中获取泛型的Class对象
在Java中获取泛型的Class对象是一个常见的需求,但由于Java类型擦除(Type Erasure)机制,直接获取泛型的具体类型信息在运行时会有一些限制,以下是几种获取泛型Class对象的方法:

使用Class.getGenericSuperclass()
对于继承自泛型父类的类,可以通过反射获取父类的泛型信息:
class Parent<T> {}
class Child extends Parent<String> {}
public class Main {
public static void main(String[] args) throws Exception {
Type genericSuperclass = Child.class.getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericSuperclass;
Type[] actualTypeArguments = pt.getActualTypeArguments();
Class<?> actualType = (Class<?>) actualTypeArguments[0];
System.out.println(actualType); // 输出: class java.lang.String
}
}
}
使用Class.getGenericInterfaces()
对于实现泛型接口的类,可以通过类似方式获取接口的泛型信息:
interface MyInterface<T> {}
class MyClass implements MyInterface<Integer> {}
public class Main {
public static void main(String[] args) throws Exception {
Type[] genericInterfaces = MyClass.class.getGenericInterfaces();
if (genericInterfaces[0] instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericInterfaces[0];
Type[] actualTypeArguments = pt.getActualTypeArguments();
Class<?> actualType = (Class<?>) actualTypeArguments[0];
System.out.println(actualType); // 输出: class java.lang.Integer
}
}
}
使用反射方法参数的泛型信息
可以通过反射获取方法参数的泛型类型:
public class Main {
public static void processList(List<String> list) {}
public static void main(String[] args) throws Exception {
Method method = Main.class.getMethod("processList", List.class);
Type[] genericParameterTypes = method.getGenericParameterTypes();
if (genericParameterTypes[0] instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericParameterTypes[0];
Type[] actualTypeArguments = pt.getActualTypeArguments();
Class<?> actualType = (Class<?>) actualTypeArguments[0];
System.out.println(actualType); // 输出: class java.lang.String
}
}
}
使用TypeToken模式(第三方库)
对于更复杂的泛型场景,可以使用如Gson库中的TypeToken模式:

import com.google.gson.reflect.TypeToken;
public class Main {
public static void main(String[] args) {
Type type = new TypeToken<List<String>>() {}.getType();
System.out.println(type); // 输出: java.util.List<java.lang.String>
}
}
在运行时传递Class对象
最简单的方法是在运行时显式传递Class对象:
public class Main {
public static <T> void process(Class<T> type) {
System.out.println(type);
}
public static void main(String[] args) {
process(String.class); // 输出: class java.lang.String
}
}
注意事项
- Java的类型擦除机制使得在运行时无法直接获取泛型的具体类型信息
- 上述方法主要适用于通过反射获取已声明的泛型信息
- 对于动态创建的泛型类型(如new ArrayList<>()),在运行时无法获取其泛型参数类型
选择哪种方法取决于你的具体使用场景和需求。
