1. getGenericSuperClass()
-
getGenericSuperclass()
方法是Java中的Class
类的一个方法,用于获取表示一个类的泛型父类的类型信息,包括泛型参数信息。它返回一个Type
对象,通常是一个ParameterizedType
,但也可能是其他类型。 -
以下是有关
getGenericSuperclass()
方法的详细解释:- 作用:
getGenericSuperclass()
方法的主要作用是在运行时获取当前类的泛型父类的类型信息。- 这在反射和泛型编程中非常有用,因为它允许您动态地了解和操作类的泛型参数信息。
- 返回值类型:
getGenericSuperclass()
方法的返回类型是Type
,这是一个Java中的通用接口,表示所有类型的超级接口。- 通常情况下,返回的
Type
对象是一个ParameterizedType
,但在某些情况下也可能是其他类型,例如Class
。
- 作用:
2. ParameterizedType
-
ParameterizedType
是 Java 中的一个接口,用于表示参数化类型,即具有泛型参数的类型。它提供了一种机制来在运行时获取和操作泛型类型的信息。下面是对ParameterizedType
的详细解释:-
什么是 ParameterizedType?
ParameterizedType
是 Java 泛型系统的一部分,用于表示类或接口的泛型类型信息。它用于捕获包含泛型参数的类的类型,例如List<String>
或Map<Integer, String>
。 -
ParameterizedType 接口的方法:
ParameterizedType
接口包含以下几个主要方法来访问泛型类型的信息:Type[] getActualTypeArguments()
: 返回一个Type
数组,其中包含了泛型参数的实际类型。例如,List<String>
的实际类型参数是String
,所以该方法将返回包含String
的Type
数组。Type getRawType()
: 返回原始类型,即没有泛型参数的类型。例如,List<String>
的原始类型是List
。Type getOwnerType()
: 如果该类型是一个成员类型,例如嵌套类,那么返回该成员类型的拥有者类型。通常情况下,这是一个包含该成员类型的外部类。
-
3. 示例
3.1 获取父类的泛型参数
-
public class People<T, Q> { class Teacher extends People<String, Integer> { } @Test public void fun() { Type type = Teacher.class.getGenericSuperclass(); System.out.println("Type:" + type); //Type:People<java.lang.String, java.lang.Integer> ParameterizedType parameterizedType = (ParameterizedType) type; System.out.println("parameterizedType:" + parameterizedType); //parameterizedType:People<java.lang.String, java.lang.Integer> // Type[] getActualTypeArguments(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for (Type type1 : actualTypeArguments) { System.out.println(type1); /*class java.lang.String class java.lang.Integer*/ } // Type getRawType(); Type rawType = parameterizedType.getRawType(); System.out.println("rawType:" + rawType); //rawType:class People // Type getOwnerType(); Type ownerType = parameterizedType.getOwnerType(); System.out.println("ownerType:" + ownerType); //ownerType:null } }
-
这段代码中,我们使用
getGenericSuperclass()
获取了Teacher
的泛型父类的Type
对象,然后使用ParameterizedType
的方法访问了原始类型和实际类型参数。总之,
getGenericSuperclass()
方法是一个用于在运行时获取类的泛型父类类型信息的重要方法。它对于反射和泛型编程非常有用,允许您动态地了解和操作泛型参数类型,以适应不同的需求。
-
3.2 获取成员变量的泛型参数
-
public class Student<T, Q> { public static Student<String, Integer> student = new Student(); public static void main(String[] args) throws NoSuchFieldException { // 1.通过反射获取成员变量 Field student = Student.class.getField("student"); // 2.获取字段的Type类型 Type studentType = student.getGenericType(); // studentType:: com.mnnu.Student<java.lang.String, java.lang.Integer> System.out.println("studentType:: " + studentType); // 3.将Type类型强转为ParameterizedType,并通过其方法获取泛型参数 if (studentType instanceof ParameterizedType) { ParameterizedType studentParameterizedType = (ParameterizedType) studentType; // studentParameterizedType:: com.mnnu.Student<java.lang.String, java.lang.Integer> System.out.println("studentParameterizedType:: " + studentParameterizedType); // Type[] getActualTypeArguments(); Type[] actualTypeArguments = studentParameterizedType.getActualTypeArguments(); for (Type type : actualTypeArguments) { System.out.println(type); /*class java.lang.String class java.lang.Integer*/ } // Type getRawType(); Type rawType = studentParameterizedType.getRawType(); System.out.println("rawType:" + rawType); //rawType:class com.mnnu.Student // Type getOwnerType(); Type ownerType = studentParameterizedType.getOwnerType(); System.out.println("ownerType:" + ownerType); //ownerType:null } } }
- 注意:当获取成员变量的Type类型时,并不是调用
getGenericSuperclass()
方法,而是getGenericType()
方法。
- 注意:当获取成员变量的Type类型时,并不是调用
3.3 获取局部变量的泛型参数
-
public class Car<T,Q> { public static void main(String[] args) { Car<String, Integer> car = new Car<>(){}; Type carType = car.getClass().getGenericSuperclass(); // type:com.mnnu.Car<java.lang.String, java.lang.Integer> System.out.println("type:" + carType); ParameterizedType parameterizedType = (ParameterizedType) carType; // parameterizedType:com.mnnu.Car<java.lang.String, java.lang.Integer> System.out.println("parameterizedType:" + parameterizedType); // Type[] getActualTypeArguments(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for (Type type : actualTypeArguments) { System.out.println(type); /*class java.lang.String class java.lang.Integer*/ } // Type getRawType(); Type rawType = parameterizedType.getRawType(); System.out.println("rawType:" + rawType); //rawType:class com.mnnu.Car // Type getOwnerType(); Type ownerType = parameterizedType.getOwnerType(); System.out.println("ownerType:" + ownerType); //ownerType:null } }
- 注意:当泛型变量是局部变量时,泛型对象必须以匿名内部类的方式定义。