博客
关于我
Java反射常见使用方法
阅读量:711 次
发布时间:2019-03-21

本文共 2003 字,大约阅读时间需要 6 分钟。

Java 反射机制详解

动态语言是一种指程序在运行时可以修改其结构的语言。例如,JavaScript 和 Python 就是典型的动态语言,而 Java 则属于半动态语言。与动态语言相反,静态语言如 C 和 C++ 的结构在编译时已经确定,无法在运行时绑定。

反射机制概念

反射机制在 Java 中具有特殊意义。它允许在程序运行时,根据类的实际类型获取信息,这对处理动态类(如外部加载的类)尤为重要。

反射机制的核心是通过反射可以获取类的信息:

  • 获取任意类的属性和方法。
  • 在运行时获取编译时无法知晓的类信息。
  • 对任意对象调用其方法和属性。
  • 反射的实现依赖于 Class 对象,其中 Class 对象描述了类的信息。这个 Class 对象是在类加载器(ClassLoader)动态加载时获取的。

    反射的应用场景

    在编译时,可使用的类型称为编译时类型,而运行时根据实际对象决定的类型称为运行时类型。例如:

    Person p = new Student();

    对于编译型 Person 和运行时类型 Student,反射机制能提供运行时类型的信息。

    当程序需要处理一些外部传入的对象时,例如通过反射获取其真实方法和属性,编译时无法预知该对象的具体类型,这种情况下反射显得尤为重要。

    Java 反射API

    Class 类 - 类创建

    获取 Class 对象的方法有三种:

  • 对象方法:通过 p.getClass() 获取当前对象的类。
  • 类属性:通过 Person.class 获取已知类的信息。
  • 静态方法:使用 Class.forName("完整包名.ClassName")动态加载类。
  • 通过类,可以获取类中的信息,如成员变量、方法和构造函数。

    Constructor 类 - 构造函数反射

    • 使用 ClassgetConstructor 方法获取指定构造函数。
    • 通过反射调用构造函数获取对象实例。

    Field 类 - 成员变量反射

    • 使用 getDeclaredField 获取类中的属性。
    • 使用 setAccessible 方法取消封装,例如修改私有字段。
    • 获取字段的修饰符信息。

    Method 类 - 方法反射

    • 使用 getDeclaredMethod 获取指定方法。
    • 调用 setAccessible 解除访问限制。
    • 通过反射调用方法。

    Modifier 类 - 修饰符信息

    • Modifier 类包含了反射中常用到的修饰符信息(如 public、private、protected)。

    反射的使用步骤

  • 获取目标类的 Class 对象。这是反射的核心。
  • 调用相关反射 API,例如获取属性或方法信息。
  • 执行反射操作,例如创建对象或修改属性值。
  • 获取 Class 对象的方式

  • 对象方法Person p = new Person(); Class clazz = p.getClass();
  • 类属性Class clazz = Person.class;
  • 静态方法Class clazz = Class.forName("包名.ClassName");
  • 通过获取 Class 对象,可以进一步获取或修改类的成员信息。

    反射缺点示例

  • 权限问题

    • 需要对方权限才能修改私有属性或静态方法。
  • 父类信息获取

    • getField 只能获取公有属性。
    • 使用 getSuperclass 获取父类引用后,可以通过 getDeclaredField 获取父类的所有属性。
  • 静态方法反射

    • 对于静态方法,调用反射时使用 null 作为目标对象。
  • 泛型参数反射

    • 泛型的类型信息在反射中会被擦除,最终只能反射为 Object 类型。
  • 反射框架:jOOR

    jOOR 是一个开源反射框架,提供了更简单的反射操作接口,但依赖 Apache Commons 代码库。

    newInstance() 方法

    Class 对象的 newInstance()

    通过 newInstance() 创建对象时,需确保类有默认空构造函数。

    Class clazz = Class.forName("reflection.Person");Object person = clazz.newInstance();

    Constructor 对象的 newInstance()

  • 获取指定构造函数:
    Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class);
  • 调用构造函数创建对象:
    Object person = constructor.newInstance("张三", 30);
  • 通过反射,可以灵活调用任意构造函数,实现高度的分类控制。

    结论

    反射机制为 Java 提供了动态操作类、成员和构造的能力。在编解析式式的应用以及动态加载类的场景中尤为重要。

    转载地址:http://uqurz.baihongyu.com/

    你可能感兴趣的文章
    MySQL Cluster 7.0.36 发布
    查看>>
    Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
    查看>>
    multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
    查看>>
    mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
    查看>>
    Multiple websites on single instance of IIS
    查看>>
    mysql CONCAT()函数拼接有NULL
    查看>>
    multiprocessing.Manager 嵌套共享对象不适用于队列
    查看>>
    multiprocessing.pool.map 和带有两个参数的函数
    查看>>
    MYSQL CONCAT函数
    查看>>
    multiprocessing.Pool:map_async 和 imap 有什么区别?
    查看>>
    MySQL Connector/Net 句柄泄露
    查看>>
    multiprocessor(中)
    查看>>
    mysql CPU使用率过高的一次处理经历
    查看>>
    Multisim中555定时器使用技巧
    查看>>
    MySQL CRUD 数据表基础操作实战
    查看>>
    multisim变压器反馈式_穿过隔离栅供电:认识隔离式直流/ 直流偏置电源
    查看>>
    mysql csv import meets charset
    查看>>
    multivariate_normal TypeError: ufunc ‘add‘ output (typecode ‘O‘) could not be coerced to provided……
    查看>>
    MySQL DBA 数据库优化策略
    查看>>
    multi_index_container
    查看>>