博客
关于我
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/

    你可能感兴趣的文章
    MySQL5.6忘记root密码(win平台)
    查看>>
    mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
    查看>>
    mysql5.7性能调优my.ini
    查看>>
    mysql5.7的安装和Navicat的安装
    查看>>
    MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
    查看>>
    MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    查看>>
    mysqlbinlog报错unknown variable ‘default-character-set=utf8mb4‘
    查看>>
    mysqldump 导出中文乱码
    查看>>
    mysqldump备份时忽略某些表
    查看>>
    mysqlreport分析工具详解
    查看>>
    MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
    查看>>
    MYSQL一直显示正在启动
    查看>>
    MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
    查看>>
    MySQL万字总结!超详细!
    查看>>
    Mysql下载以及安装(新手入门,超详细)
    查看>>
    mysql中cast() 和convert()的用法讲解
    查看>>
    mysql中floor函数的作用是什么?
    查看>>
    MySQL中group by 与 order by 一起使用排序问题
    查看>>
    mysql中having的用法
    查看>>
    mysql中int、bigint、smallint 和 tinyint的区别、char和varchar的区别详细介绍
    查看>>