马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
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():获取范例变量的上界。
- class Person<K extends Comparable & Serializable, V> {
- K key;
- V value;
- }
- public class Test {
- public static void main(String[] args) throws NoSuchFieldException {
- Person<String, Double> person = new Person<String, Double>();
- // 获取变量的Field
- Field keyField = person.getClass().getDeclaredField("key");
- Field valueField = person.getClass().getDeclaredField("value");
- // 获取类型变量
- TypeVariable keyType = (TypeVariable) keyField.getGenericType();
- TypeVariable valueType = (TypeVariable) valueField.getGenericType();
- // 获取类型变量名
- System.out.println(keyType.getName()); // K
- // 获取类型变量的泛型类
- System.out.println(keyType.getGenericDeclaration()); // class Person
- System.out.println(valueType.getName()); // V
- System.out.println(valueType.getGenericDeclaration()); // class Person
- // 获取上界
- for (Type type : keyType.getBounds()) {
- System.out.println(type);
- }
- // interface java.lang.Comparable
- // interface java.io.Serializable
- for (Type type : valueType.getBounds()) {
- System.out.println(type);
- }
- // class java.lang.Object
- }
- }
复制代码 ParameterizedType
表现参数化范例,即带有现实范例参数的泛型范例,如 List<String>、Map<Integer, String> 等。
- getRawType():获取原始范例。
- getActualTypeArguments():获取现实范例参数的数组。
- class Person {
- Map<String, Integer> map;
- }
- public class Test {
- public static void main(String[] args) throws NoSuchFieldException {
- Field field = Person.class.getDeclaredField("map");
- // 获取泛型类型
- Type genericType = field.getGenericType();
- System.out.println(genericType); // java.util.Map<java.lang.String, java.lang.Integer>
- // 转参数化类型
- ParameterizedType pType = (ParameterizedType) genericType;
- // 获得原始类型
- Type rawType = pType.getRawType();
- System.out.println(rawType); // interface java.util.Map
- // 获取实际类型
- for (Type t : pType.getActualTypeArguments()) {
- System.out.println("泛型实际类型参数:" + t.getTypeName());
- }
- //泛型实际类型参数:java.lang.String
- //泛型实际类型参数:java.lang.Integer
- }
- }
复制代码 GenericeArrayType
表现元素范例是参数化范例大概范例变量的数组范例,如:List<String>[]。
- public class Test {
- private List<String>[] array;
- public static void main(String[] args) throws NoSuchFieldException {
- // 获取field
- Field field = Test.class.getDeclaredField("array");
- // 获取泛型类型
- Type genericType = field.getGenericType();
- // 转为泛型数组类型
- if (genericType instanceof GenericArrayType) {
- GenericArrayType genericArrayType = (GenericArrayType) genericType;
- // 获取数组类型
- Type genericComponentType = genericArrayType.getGenericComponentType();
- // 转为参数化类型
- if (genericComponentType instanceof ParameterizedType) {
- ParameterizedType pType = (ParameterizedType) genericComponentType;
- // 获取实际类型参数
- Type[] actualTypeArguments = pType.getActualTypeArguments();
- for (Type actualTypeArgument : actualTypeArguments) {
- System.out.println("实际类型参数:" + actualTypeArgument.getTypeName());
- }
- }
- }
- }
- }
- // 实际类型参数:java.lang.String
复制代码 方法
- getTypeParameters():Class 类和 Method 类都提供了 getTypeParameters() 方法,用于获取类或方法中声明的范例变量。
- getGenericSuperClass():Class 类的 getGenericSuperclass() 方法用于获取当前类的直接父类的泛型范例。
- getGenericReturnType():Method 类的 getGenericReturnType() 方法用于获取方法返回值的泛型范例。
getTypeParameters()
- 在 Class 类:用于获取类大概接口的泛型的范例变量。
- 在 Method 类:用于获取方法的泛型的范例变量。
- // 获取类的泛型信息:
- public class Test<T, U> {
- public static void main(String[] args) throws NoSuchFieldException {
- TypeVariable<?>[] typeParameters = Test.class.getTypeParameters();
- for (TypeVariable<?> typeParameter : typeParameters) {
- System.out.println("类型变量名称:" + typeParameter.getName());
- Type[] bounds = typeParameter.getBounds();
- for (java.lang.reflect.Type type : bounds) {
- System.out.println("上界:" + type.getTypeName());
- }
- }
- }
- }
- // 类型变量名称:T
- // 上界:java.lang.Object
- // 类型变量名称:U
- // 上界:java.lang.Object
复制代码- // 获取方法的泛型信息:
- public class Test {
- public <V, W> void genericMethod(V v, W w) {
- }
- public static void main(String[] args) throws NoSuchMethodException {
- Method method = Test.class.getMethod("genericMethod", Object.class, Object.class);
- TypeVariable<Method>[] typeParameters = method.getTypeParameters();
- for (TypeVariable<?> typeParameter : typeParameters) {
- System.out.println("方法的类型变量:" + typeParameter.getName());
- Type[] types = typeParameter.getBounds();
- for (Type type : types) {
- System.out.println("上界:" + type.getTypeName());
- }
- }
- }
- }
- // 方法的类型变量:V
- // 上界:java.lang.Object
- // 方法的类型变量:W
- // 上界:java.lang.Object
复制代码 getGenericSuperClass()
获取父类的泛型范例。
- // 父类有泛型:
- class MyArrayList extends ArrayList<String> {
- }
- public class Test {
- public static void main(String[] args) throws NoSuchMethodException {
- Type superclass = MyArrayList.class.getGenericSuperclass();
- if (superclass instanceof ParameterizedType) {
- ParameterizedType pType = (ParameterizedType) superclass;
- Type[] actualTypeArguments = pType.getActualTypeArguments();
- for (Type type : actualTypeArguments) {
- System.out.println("父类实际类型参数:" + type);
- }
- }
- }
- }
- // 父类实际类型参数:class java.lang.String
复制代码- // 父类没有泛型:
- class MyClass {
- }
- public class Test {
- public static void main(String[] args) throws NoSuchMethodException {
- Type superclass = MyClass.class.getGenericSuperclass();
- if (superclass instanceof Class) {
- Class<?> parentClass = (Class<?>) superclass;
- System.out.println("父类类型:" + parentClass);
- }
- }
- }
- // 父类类型:class java.lang.Object
复制代码 getGenericReturnType()
获取返回值的范例范例。
- // 返回值有泛型:
- public class Test {
- public List<String> getStringList() {
- return null;
- }
- public static void main(String[] args) throws NoSuchMethodException {
- Method method = Test.class.getMethod("getStringList");
- Type returnType = method.getGenericReturnType();
- if (returnType instanceof ParameterizedType) {
- ParameterizedType pType = (ParameterizedType) returnType;
- Type[] actualTypeArguments = pType.getActualTypeArguments();
- for (Type type : actualTypeArguments) {
- System.out.println("返回值的实际类型参数:" + type.getTypeName());
- }
- }
- }
- }
- // 返回值的实际类型参数:java.lang.String
复制代码- // 返回值没有泛型:
- public class Test {
- public int getInt() {
- return 0;
- }
- public static void main(String[] args) throws NoSuchMethodException {
- Method method = Test.class.getMethod("getInt");
- Type returnType = method.getGenericReturnType();
- if (returnType instanceof Class) {
- Class<?> c = (Class) returnType;
- System.out.println("返回值类型:" + c.getName());
- }
- }
- }
- // 返回值类型:int
复制代码 |