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

本文共 2004 字,大约阅读时间需要 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 中开启二进制日志(Binlog)
    查看>>
    MySQL 中文问题
    查看>>
    MySQL 中日志的面试题总结
    查看>>
    mysql 中的all,5分钟了解MySQL5.7中union all用法的黑科技
    查看>>
    MySQL 中的外键检查设置:SET FOREIGN_KEY_CHECKS = 1
    查看>>
    Mysql 中的日期时间字符串查询
    查看>>
    mysql 中索引的问题
    查看>>
    MySQL 中锁的面试题总结
    查看>>
    MySQL 中随机抽样:order by rand limit 的替代方案
    查看>>
    MySQL 为什么需要两阶段提交?
    查看>>
    mysql 为某个字段的值加前缀、去掉前缀
    查看>>
    mysql 主从
    查看>>
    mysql 主从 lock_mysql 主从同步权限mysql 行锁的实现
    查看>>
    mysql 主从互备份_mysql互为主从实战设置详解及自动化备份(Centos7.2)
    查看>>
    mysql 主从关系切换
    查看>>
    MYSQL 主从同步文档的大坑
    查看>>
    mysql 主键重复则覆盖_数据库主键不能重复
    查看>>
    Mysql 事务知识点与优化建议
    查看>>
    Mysql 优化 or
    查看>>
    mysql 优化器 key_mysql – 选择*和查询优化器
    查看>>