zoukankan      html  css  js  c++  java
  • java核心学习(三十八) 通过反射查看类信息

      反射实现了java代码对java代码的操作。

    一、获得Class对象

      有下列四种方式:

    •     使用Class类的forName(String className) 静态方法,该静态方法需要传入类的全限定名称字符串。
    •     调用某个类的class属性来获得该类对应的class对象。
    •     调用某个对象的getClass()方法。
    •     调用ClassLoader实例对象的loadClass方法。

      由前两节对类加载的学习,可以了解到使用第二种和第三种方法获得Class对象,JVM已经将该类初始化,第三种方法由于创建了该类的实例,所以还会初始化该类的一个对象(及执行了非静态变量赋值+初始化代码块+构造函数)。

      使用第一种方式,通过查看forName方法的源代码可以发现,默认会初始化类

      

      上述方法调用了forName0的native方法:该方法对于是否初始化该类的参数 initialize 设置为true,并且传入了调用者(caller)的类加载器。也可以使用forName的重载方法设置initialize为false。

      而使用第四种方式,loadClass方法源代码如下

      

      这里的resolve参数代表“解析”,即类加载过程中第二步“连接”中的第三部分“解析”,默认情况不解析,也可以使用loadClass的重载方法将resolve设置为true。也就是说loadClass方法不会初始化该类。

    二、从Class对象中获取信息

      先来整理一下Class对象中通常获取的类信息:

        Constructor<T> 这里的反省T代表构造器创建的对象类型。

        Method

        Field

        <A extends Annotation> A ,由于使用@interface自定义注解时,都默认实现了Annotation接口,所以这里使用泛型A代表使用的

        Class[] 内部类

        Interfaces 该Class实现的全部接口

        Superclass

        Package 包

        Modifiers 该类所有的修饰符

        Name、SimpleName

        TypeVariable<Class<T>>[] ,由getTypeParameters方法返回,该数组代表类的定义中包含的泛型类型声明,如果如果泛型声明的一般签名不符合Java虚拟机规范中指定的格式,则抛出GenericSignatureFormatError错误。

      对于类的成员,又分为getEnclosing*、getDeclared*、getDeclaringClass、get*

        它们的区别为:getEnclosing*返回一个Class、Method、Constructor对象,当前类定义在该Class、Method、Constructor中。

               getDeclaringClass,返回一个类,当前类定义在这个类中作为成员(内部类或接口)。

               getDeclared*,返回当前类中定义的*,与访问修饰符所限定的权限无关。

               get*返回public的*。

      上述信息都可以通过Class对象的getXXX方法来获得,具体方法的使用可以查阅文档。

      除了getXXX方法,Class对象还提供了isXXX方法来帮助判断。

    三、java8新增的方法参数反射

      java8在java.lang.reflect包下新增了一个Executable抽象基类,该对象代表可执行的类成员,该类派生了Constructor、Method两个字类。

      Executable类提供了大量方法来获取修饰该方法或构造器的注解信息,还提供了isVarArgs()方法来判断该方法或构造器是否包含数量可变的形参,该类还提供了下面两个方法来获取该方法的参数个数和形参名

      int getParameterCount();

      Parameter[] getParameters。

      其中Parameter类也是java8新增的类。通过Parameter类可以获取方法参数上面的信息,包括形参名、形参类型、泛型信息、注解信息等等。

      由于javac在编译java文件时会忽略掉形参名,所以若想利用反射获取形参名,需要在编译时加入-parameters 参数,即可在编译时保留形参名信息。

      获得Class的信息是在代码中动态操作Class的基础,下一节学习如何利用反射来动态操作代码。

  • 相关阅读:
    海思HISI 3518EV200 AEC回音消除+ANR语音降噪(转)
    重磅消息 | 2020年最新全栈测试开发技能实战指南(第1期)
    推荐一款Python开源库,技术人必备的造数据神器!
    DevOps研发模式下「产品质量度量」方案实践
    自动化测试实战技巧:「用例失败重试机制」实现方案分享
    C#/VB.NET 在Word中添加条码、二维码
    Java 在PDF中绘制形状(基于Spire.Cloud.SDK for Java)
    Java 添加条码、二维码到Word文档
    Java 添加、下载、读取PDF附件信息(基于Spire.Cloud.SDK for Java)
    Java 添加、提取PDF中的图片
  • 原文地址:https://www.cnblogs.com/Theshy/p/7760439.html
Copyright © 2011-2022 走看看