首页 > 其他分享 >20230602 反射中的泛型信息

20230602 反射中的泛型信息

时间:2023-09-05 09:46:43浏览次数:34  
标签:lang 反射 java System println 泛型 out Type 20230602

介绍

Java 泛型的突出特性之一是在虚拟机中擦除泛型类型,但是擦除的类仍然保留原先泛型的一些微弱记忆。例如,原始 Pair 类知道它源自于泛型类 Pair<T> ,尽管无法区分是 Pair<String> 还是 Pair<Integer>

为了描述泛型类型声明,java.lang.reflect 包中提供了接口 Type ,包含以下子类型:

  • Class 类,描述具体类型
  • TypeVariable 接口,描述类型变量(如 T extends Comparable<? super T> )
  • WildcardType 接口, 描述通配符 (如 ? super T )
  • ParameterizedType 接口, 描述泛型类或接口类型(如 Comparable<? super T> )
  • GenericArrayType 接口, 描述泛型数组(如 T[]

后四个类型是接口,虚拟机会实例化实现这些接口的适当的类

获取 Type

java.lang.Class

  • getTypeParameters
    • TypeVariable<Class<T>>[] getTypeParameters()
    • 如果这个类型声明为泛型类型,则获得泛型类型变量
  • getGenericSuperclass
    • Type getGenericSuperclass()
    • 获得这个类型所声明超类的泛型类型
  • getGenericInterfaces
    • Type[] getGenericInterfaces()
    • 获得这个类型所声明接口的泛型类型

java.lang.reflect.Method

  • getTypeParameters
    • TypeVariable<Method>[] getTypeParameters()
  • getGenericReturnType
    • Type getGenericReturnType()
    • 获得这个方法声明的泛型返回类型
  • getGenericParameterTypes
    • Type[] getGenericParameterTypes()
    • 获得这个方法声明的泛型参数类型

java.lang.reflect.Type

介绍

  • java.lang.reflect.Type
  • public interface Type
  • 父接口

API

default

  • getTypeName

java.lang.reflect.TypeVariable

介绍

  • java.lang.reflect.TypeVariable
  • public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement

API

  • getBounds
    • Type[] getBounds();
    • 获得这个类型变量的子类限定
  • getAnnotatedBounds
    • AnnotatedType[] getAnnotatedBounds();
    • 获得这个类型变量的子类限定上的注解信息
  • getName
  • getGenericDeclaration
    • D getGenericDeclaration();
    • 获得这个类型变量的泛型声明

java.lang.reflect.WildcardType

介绍

  • java.lang.reflect.WildcardType
  • public interface WildcardType extends Type

API

  • getUpperBounds
    • Type[] getUpperBounds();
    • 获得这个类型变量的子类(extends)限定
  • getLowerBounds
    • Type[] getLowerBounds();
    • 获得这个类型变量的超类(super)限定

java.lang.reflect.ParameterizedType

介绍

  • java.lang.reflect.ParameterizedType
  • public interface ParameterizedType extends Type
  • 参数化类型,例如 Collection<String>

API

  • getActualTypeArguments
    • Type[] getActualTypeArguments();
    • 获得这个参数化类型声明的类型参数
  • getRawType
    • Type getRawType();
    • 获得这个参数化类型的原始类型
  • getOwnerType
    • Type getOwnerType();
    • 如果是内部类型,返回其外部类型;如果是一个顶级类型,返回 null

java.lang.reflect.GenericArrayType

介绍

  • java.lang.reflect.GenericArrayType
  • public interface GenericArrayType extends Type

API

  • getGenericComponentType
    • Type getGenericComponentType();
    • 获得这个数组类型声明的泛型元素类型

代码示例

示例一

public class TestTypeVariable<T extends Number & Comparable<? super T>> {


    public static void main(String[] args) {
        Class<TestTypeVariable> testTypeVariableClass = TestTypeVariable.class;
        TypeVariable<Class<TestTypeVariable>>[] typeParameters = testTypeVariableClass.getTypeParameters();

        for (TypeVariable<Class<TestTypeVariable>> typeParameter : typeParameters) {
            System.out.println("typeParameter :: " + typeParameter);
            System.out.println("typeParameter.getClass() :: " + typeParameter.getClass());

            Class<TestTypeVariable> genericDeclaration = typeParameter.getGenericDeclaration();
            System.out.println("typeParameter.getGenericDeclaration() :: " + genericDeclaration);



            Type[] bounds = typeParameter.getBounds();
            for (int i = 0; i < bounds.length; i++) {
                Type bound = bounds[i];
                System.out.println("====================== i = " + i);
                System.out.println("bound :: " + bound);
                System.out.println("bound.getClass() :: " + bound.getClass());

                if (bound instanceof ParameterizedType parameterizedType) {
                    Type rawType = parameterizedType.getRawType();
                    System.out.println("rawType :: " + rawType);
                    System.out.println("rawType.getClass() :: " + rawType.getClass());

                    System.out.println("parameterizedType.getOwnerType() :: " + parameterizedType.getOwnerType());

                    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                    for (int j = 0; j < actualTypeArguments.length; j++) {
                        Type actualTypeArgument = actualTypeArguments[j];
                        System.out.println("-------------- j = " + j);
                        System.out.println("actualTypeArgument :: " + actualTypeArgument);
                        System.out.println("actualTypeArgument.getClass() :: " + actualTypeArgument.getClass());

                        if (actualTypeArgument instanceof WildcardType wildcardType) {
                            Type[] lowerBounds = wildcardType.getLowerBounds();
                            Type[] upperBounds = wildcardType.getUpperBounds();

                            System.out.println("lowerBounds :: " + Arrays.toString(lowerBounds));
                            System.out.println("upperBounds :: " + Arrays.toString(upperBounds));
                        }
                    }
                }
            }
        }
    }
}

输出结果

typeParameter :: T
typeParameter.getClass() :: class sun.reflect.generics.reflectiveObjects.TypeVariableImpl
typeParameter.getGenericDeclaration() :: class study.hwj.v1p8.generic.TestTypeVariable
====================== i = 0
bound :: class java.lang.Number
bound.getClass() :: class java.lang.Class
====================== i = 1
bound :: java.lang.Comparable<? super T>
bound.getClass() :: class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
rawType :: interface java.lang.Comparable
rawType.getClass() :: class java.lang.Class
parameterizedType.getOwnerType() :: null
-------------- j = 0
actualTypeArgument :: ? super T
actualTypeArgument.getClass() :: class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl
lowerBounds :: [T]
upperBounds :: [class java.lang.Object]

示例二

public class TestGeneric<T> {

    public TestGeneric() {
        Type type = getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType parameterizedType) {
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println("actualTypeArgument.getClass() :: " + actualTypeArgument.getClass());
                if (actualTypeArgument instanceof ParameterizedType parameterizedType1) {
                    Type[] actualTypeArguments1 = parameterizedType1.getActualTypeArguments();
                    System.out.println("getActualTypeArguments :: " + Arrays.toString(actualTypeArguments1));

                    Type rawType = parameterizedType1.getRawType();
                    System.out.println("rawType :: " + rawType);

                } else {
                    System.out.println("actualTypeArgument :: " + actualTypeArgument);
                }
            }
        }
    }

    public static void main(String[] args) {
        TestGeneric<List<String>> testGeneric = new TestGeneric<>() {
        };  // TestGeneric 的匿名子类
        System.out.println(testGeneric.getClass());

        System.out.println("========================");

        TestGeneric<String> testGeneric2 = new TestGeneric<>();     // TestGeneric 类
        System.out.println(testGeneric2);


    }
}

输出结果

actualTypeArgument.getClass() :: class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
getActualTypeArguments :: [class java.lang.String]
rawType :: interface java.util.List
class study.hwj.v1p8.TestGeneric$1
========================
study.hwj.v1p8.TestGeneric@52cc8049

标签:lang,反射,java,System,println,泛型,out,Type,20230602
From: https://www.cnblogs.com/huangwenjie/p/17545289.html

相关文章

  • [个人笔记][C#]反射和特性学习笔记
    反射通过Type类型的实例来访问类型的元数据通过obj.GetType()或typeof()获取一个Type类型的实例在Type类型的实例上通过GetProperties(),GetMethods(),GetCustomAttributes()访问类型的各种东西GetType()只能在实例上调用,typeof()给一个类型名就行,它是在编译时求值的验证一个......
  • PCI-5565反射内存卡
    PCI-5565反射内存卡是一种用于实时网络的硬件设备。它基于反射内存网的原理,通过光纤连接多台计算机,形成网络节点,并且每个节点上的网络内存卡存储着其他节点的共享数据拷贝。该反射内存卡可以插在多种总线的主板上,如VME、PCI、CompactPCI、PMC接口等。它具有以下特点和优势:内存容量......
  • 2.反射
    二Reflection1.正常的调用//1.加载程序集参数:【完整程序集名称】Assemblyassembly=Assembly.Load("Common");//2.获取类型参数:【完整类型名称】Typetype=assembly.GetType("Common.Implemented.MySqlHelper");//3.创建类型实例objectinstance=Activator.Crea......
  • 1.Generic-泛型
    一Generic如果使用Object会有哪些问题?1.存在装箱、拆箱的性能问题2.如果使用额外元素,会存在类型不安全的问题.1引入泛型:延迟声明2如何声明和使用泛型3泛型的好处和原理4泛型类、泛型方法、泛型接口、泛型委托5泛型约束6协变逆变7泛型缓存泛型Generic本......
  • Java泛型
    Java泛型1.泛型概述泛型的本质是为了参数化类型(即限制参数类型为我们指定泛型类型)如这样:给list集合指定类型String//比如给List集合指定一个泛型(String),那么存入List集合中的元素必须要是String类型List<String>list=newArrayList<String>();2.泛型的优点限制变量的类......
  • 泛型
    泛型(Generics)UTS支持泛型(Generics)特性,允许您编写更通用、可重用的代码,同时提高类型安全性。#定义泛型泛型使用尖括号 <> 声明一个或多个泛型参数。#泛型函数泛型函数的泛型参数定义在函数参数的圆括号之前。functiontest<T>(arg:T):T{returnarg}conststr:s......
  • C#中泛型集合List<T>反序列化问题及解决方法
    一、普通类型的反序列化程序集问题及处理方法在一些应用系统中常常有两个子系统软件A与B:A软件序列化一个数据文件,该文件将在B软件中使用。例如,在15年的交通运输部小样本调查数据的审核软件中,A软件就是笔者自己用的审核规则编制软件;B软件则是给用户使用的审核小样本调查数据的客户......
  • 反射
    反射简介:反射指程序可以访问、检测和修改它本身状态或行为的一种能力。程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或......
  • 反射和动态代理
    反射允许对成员变量,成员方法和构造方法的信息进行编程访问。1、获取Class对象(字节码文件对象)的三种方式①、Class.forName(“全类名”)(在源代码阶段使用)②、类名.class (在加载阶段中使用)③、对象.getClass() (在运行阶段使用)publicclassTest{publicstat......
  • 25. 反射
    一、什么是反射  反射,本质上就是通过字符的形式去操作对象/模块中的成员。在Python中,我们可以通过三个内置函数去实现反射相关的功能。getattr(object,name)#获取对象中的成员setattr(object,name,value)#设置对象中的成员hasattr(object,......