杰瑞科技汇

Java如何获取泛型的Class对象?

在Java中获取泛型的Class对象

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

Java如何获取泛型的Class对象?-图1
(图片来源网络,侵删)

使用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模式:

Java如何获取泛型的Class对象?-图2
(图片来源网络,侵删)
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
    }
}

注意事项

  1. Java的类型擦除机制使得在运行时无法直接获取泛型的具体类型信息
  2. 上述方法主要适用于通过反射获取已声明的泛型信息
  3. 对于动态创建的泛型类型(如new ArrayList<>()),在运行时无法获取其泛型参数类型

选择哪种方法取决于你的具体使用场景和需求。

分享:
扫描分享到社交APP
上一篇
下一篇