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的基础,下一节学习如何利用反射来动态操作代码。

  • 相关阅读:
    树莓派pwm驱动好盈电调及伺服电机
    wiringPi库的pwm配置及使用说明
    未能加载文件或程序集“**, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。试图加载格式不正确的程序。
    poj 1700 Crossing River(贪心)
    前缀 树 背单词(Remember the Word,LA 3942)
    c/c++ double的数字 转成字符串后 可以有效的避免精度要求不高的数
    hdu acm 2154(多解取一解)
    hdu 5104 Primes Problem(prime 将三重循环化两重)
    hdu 2203亲和串 (kmp)
    hdu 2519 新生晚会 排列组合
  • 原文地址:https://www.cnblogs.com/Theshy/p/7760439.html
Copyright © 2011-2022 走看看