Java 反射之泛型

[复制链接]
发表于 2025-12-10 00:31:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Java 反射之泛型

概述

在 Java 中,泛型是一项强盛的特性,它提供了编译时范例安全查抄机制,答应在界说类、接口和方法时利用范例参数。然而,由于 Java 的泛型存在范例擦除机制,在运行时泛型的具体范例信息通常会被擦除。不外,Java 反射机制提供了一些工具和接口,让我们在某些场景下可以或许在运行时获取泛型的干系信息。
范例



  • TypeVariable:表现泛型类中声明的范例变量。如:class MyClass<T> 此中的 T 就是一个范例变量。
  • ParamterizedType:表现参数化范例,即带有现实泛型参数的泛型范例。获取泛型范例的现实范例参数信息,如:List<String>、Map<Integer, String>。
  • GenericeArrayType:表现元素范例是参数化范例大概范例变量的数组范例。用于获取泛型数组元素的范例信息,如:List<String>[]。
TypeVariable

表现泛型类中声明的范例变量。如:class MyClass<T> 此中的 T 就是一个范例变量。


  • getName():获取范例变量的名称。
  • getBounds():获取范例变量的上界。
  1. class Person<K extends Comparable & Serializable, V> {
  2.     K key;
  3.     V value;
  4. }
  5. public class Test {
  6.     public static void main(String[] args) throws NoSuchFieldException {
  7.         Person<String, Double> person = new Person<String, Double>();
  8.         // 获取变量的Field
  9.         Field keyField = person.getClass().getDeclaredField("key");
  10.         Field valueField = person.getClass().getDeclaredField("value");
  11.         // 获取类型变量
  12.         TypeVariable keyType = (TypeVariable) keyField.getGenericType();
  13.         TypeVariable valueType = (TypeVariable) valueField.getGenericType();
  14.         // 获取类型变量名
  15.         System.out.println(keyType.getName()); // K
  16.         // 获取类型变量的泛型类
  17.         System.out.println(keyType.getGenericDeclaration()); // class Person
  18.         System.out.println(valueType.getName()); // V
  19.         System.out.println(valueType.getGenericDeclaration()); // class Person
  20.         // 获取上界
  21.         for (Type type : keyType.getBounds()) {
  22.             System.out.println(type);
  23.         }
  24.         // interface java.lang.Comparable
  25.         // interface java.io.Serializable
  26.         for (Type type : valueType.getBounds()) {
  27.             System.out.println(type);
  28.         }
  29.         // class java.lang.Object
  30.     }
  31. }
复制代码
ParameterizedType

表现参数化范例,即带有现实范例参数的泛型范例,如 List<String>、Map<Integer, String> 等。


  • getRawType():获取原始范例。
  • getActualTypeArguments():获取现实范例参数的数组。
  1. class Person {
  2.     Map<String, Integer> map;
  3. }
  4. public class Test {
  5.     public static void main(String[] args) throws NoSuchFieldException {
  6.         Field field = Person.class.getDeclaredField("map");
  7.         // 获取泛型类型
  8.         Type genericType = field.getGenericType();
  9.         System.out.println(genericType); // java.util.Map<java.lang.String, java.lang.Integer>
  10.         // 转参数化类型
  11.         ParameterizedType pType = (ParameterizedType) genericType;
  12.         // 获得原始类型
  13.         Type rawType = pType.getRawType();
  14.         System.out.println(rawType); // interface java.util.Map
  15.         // 获取实际类型
  16.         for (Type t : pType.getActualTypeArguments()) {
  17.             System.out.println("泛型实际类型参数:" + t.getTypeName());
  18.         }
  19.         //泛型实际类型参数:java.lang.String
  20.         //泛型实际类型参数:java.lang.Integer
  21.     }
  22. }
复制代码
GenericeArrayType

表现元素范例是参数化范例大概范例变量的数组范例,如:List<String>[]。
  1. public class Test {
  2.     private List<String>[] array;
  3.     public static void main(String[] args) throws NoSuchFieldException {
  4.         // 获取field
  5.         Field field = Test.class.getDeclaredField("array");
  6.         // 获取泛型类型
  7.         Type genericType = field.getGenericType();
  8.         // 转为泛型数组类型
  9.         if (genericType instanceof GenericArrayType) {
  10.             GenericArrayType genericArrayType = (GenericArrayType) genericType;
  11.             // 获取数组类型
  12.             Type genericComponentType = genericArrayType.getGenericComponentType();
  13.             // 转为参数化类型
  14.             if (genericComponentType instanceof ParameterizedType) {
  15.                 ParameterizedType pType = (ParameterizedType) genericComponentType;
  16.                 // 获取实际类型参数
  17.                 Type[] actualTypeArguments = pType.getActualTypeArguments();
  18.                 for (Type actualTypeArgument : actualTypeArguments) {
  19.                     System.out.println("实际类型参数:" + actualTypeArgument.getTypeName());
  20.                 }
  21.             }
  22.         }
  23.     }
  24. }
  25. // 实际类型参数:java.lang.String
复制代码
方法



  • getTypeParameters():Class 类和 Method 类都提供了 getTypeParameters() 方法,用于获取类或方法中声明的范例变量。
  • getGenericSuperClass():Class 类的 getGenericSuperclass() 方法用于获取当前类的直接父类的泛型范例。
  • getGenericReturnType():Method 类的 getGenericReturnType() 方法用于获取方法返回值的泛型范例。
getTypeParameters()



  • 在 Class 类:用于获取类大概接口的泛型的范例变量。
  • 在 Method 类:用于获取方法的泛型的范例变量。
  1. // 获取类的泛型信息:
  2. public class Test<T, U> {
  3.     public static void main(String[] args) throws NoSuchFieldException {
  4.         TypeVariable<?>[] typeParameters = Test.class.getTypeParameters();
  5.         for (TypeVariable<?> typeParameter : typeParameters) {
  6.             System.out.println("类型变量名称:" + typeParameter.getName());
  7.             Type[] bounds = typeParameter.getBounds();
  8.             for (java.lang.reflect.Type type : bounds) {
  9.                 System.out.println("上界:" + type.getTypeName());
  10.             }
  11.         }
  12.     }
  13. }
  14. // 类型变量名称:T
  15. // 上界:java.lang.Object
  16. // 类型变量名称:U
  17. // 上界:java.lang.Object
复制代码
  1. // 获取方法的泛型信息:
  2. public class Test {
  3.     public <V, W> void genericMethod(V v, W w) {
  4.     }
  5.     public static void main(String[] args) throws NoSuchMethodException {
  6.         Method method = Test.class.getMethod("genericMethod", Object.class, Object.class);
  7.         TypeVariable<Method>[] typeParameters = method.getTypeParameters();
  8.         for (TypeVariable<?> typeParameter : typeParameters) {
  9.             System.out.println("方法的类型变量:" + typeParameter.getName());
  10.             Type[] types = typeParameter.getBounds();
  11.             for (Type type : types) {
  12.                 System.out.println("上界:" + type.getTypeName());
  13.             }
  14.         }
  15.     }
  16. }
  17. // 方法的类型变量:V
  18. // 上界:java.lang.Object
  19. // 方法的类型变量:W
  20. // 上界:java.lang.Object
复制代码
getGenericSuperClass()

获取父类的泛型范例。
  1. // 父类有泛型:
  2. class MyArrayList extends ArrayList<String> {
  3. }
  4. public class Test {
  5.     public static void main(String[] args) throws NoSuchMethodException {
  6.         Type superclass = MyArrayList.class.getGenericSuperclass();
  7.         if (superclass instanceof ParameterizedType) {
  8.             ParameterizedType pType = (ParameterizedType) superclass;
  9.             Type[] actualTypeArguments = pType.getActualTypeArguments();
  10.             for (Type type : actualTypeArguments) {
  11.                 System.out.println("父类实际类型参数:" + type);
  12.             }
  13.         }
  14.     }
  15. }
  16. // 父类实际类型参数:class java.lang.String
复制代码
  1. // 父类没有泛型:
  2. class MyClass {
  3. }
  4. public class Test {
  5.     public static void main(String[] args) throws NoSuchMethodException {
  6.         Type superclass = MyClass.class.getGenericSuperclass();
  7.         if (superclass instanceof Class) {
  8.             Class<?> parentClass = (Class<?>) superclass;
  9.             System.out.println("父类类型:" + parentClass);
  10.         }
  11.     }
  12. }
  13. // 父类类型:class java.lang.Object
复制代码
getGenericReturnType()

获取返回值的范例范例。
  1. // 返回值有泛型:
  2. public class Test {
  3.     public List<String> getStringList() {
  4.         return null;
  5.     }
  6.     public static void main(String[] args) throws NoSuchMethodException {
  7.         Method method = Test.class.getMethod("getStringList");
  8.         Type returnType = method.getGenericReturnType();
  9.         if (returnType instanceof ParameterizedType) {
  10.             ParameterizedType pType = (ParameterizedType) returnType;
  11.             Type[] actualTypeArguments = pType.getActualTypeArguments();
  12.             for (Type type : actualTypeArguments) {
  13.                 System.out.println("返回值的实际类型参数:" + type.getTypeName());
  14.             }
  15.         }
  16.     }
  17. }
  18. // 返回值的实际类型参数:java.lang.String
复制代码
  1. // 返回值没有泛型:
  2. public class Test {
  3.     public int getInt() {
  4.         return 0;
  5.     }
  6.     public static void main(String[] args) throws NoSuchMethodException {
  7.         Method method = Test.class.getMethod("getInt");
  8.         Type returnType = method.getGenericReturnType();
  9.         if (returnType instanceof Class) {
  10.             Class<?> c = (Class) returnType;
  11.             System.out.println("返回值类型:" + c.getName());
  12.         }
  13.     }
  14. }
  15. // 返回值类型:int
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表