java反射机制原理、获取Class方式和其应用场景

news/2025/2/16 1:12:42/

1、反射是什么:

        反射是一种动态地获取和操作类信息的行为。类信息包括类的属性、方法、构造函数等。

        类信息在Java中通常存储在.class文件中。当我们编写Java代码并进行编译时,编译器(javac)将源代码转换为字节码,并将字节码保存在.class文件中。

         在运行时,当我们使用反射来获取类的信息时,实际上是通过读取和解析.class文件来获取类的结构信息。反射机制允许我们在运行时动态地加载和操作类的信息,而不需要在编译时明确知道类的类型。

2、 获取Class对象以及其对其操作:

  获取class对象(三种方式对应三个阶段)

 反射代码简单示例:

public class ReflexDemo {public static void main(String[] args) throws Exception{Class<person> clazz = person.class;//通过newInstance()创建对象person person = clazz.newInstance();//获取方法名为getName的方法Method changeName = clazz.getMethod("changeName", String.class);//调用了person对象的chanName方法changeName.invoke(person, "wkx");}
}class person {private String name;Person(){}Person(String name){this.name = name;}public void changeName(String name){this.name =name;System.out.println("我将名字改为了"+name);}
}

 3、操作Class对象的API

  • 变量信息:Filed
  • 成员方法:Method
  • 构造器:Constructor
  • 注解信息:Annotation
  • 权限修饰符:Modifier

创建类的实例的方式:

//创建类的实例:可以使用以下方法创建类的实例:Person person1 = clazz.newInstance();// 调用无参构造方法创建实例Constructor<Person> declaredConstructor = clazz.getDeclaredConstructor(String.class);// 获取指定构造方法,第二个参数为构造方法参数类型Person person2 = declaredConstructor.newInstance("小明");// 调用构造方法创建实例,args为构造方法参数的值

对于类的字段信息的操作:

//获取类的字段信息:可以使用以下方法获取类的字段信息:    
Field[] fields1 = clazz.getFields();// 获取所有字段,不包括私有字段
Field[] fields = clazz.getDeclaredFields(); // 获取所有字段,包括私有字段
Field field = clazz.getDeclaredField("name"); // 获取指定字段//对于修饰符为private的变量,,不能直接通过反射对其赋值取值,要进行暴力反射
field.setAccessible(true); // 如果字段是私有的,需要设置可访问性
field.set(person1, "wuing"); // 修改字段值,person1为字段所属对象,value为新的字段值

获取类的方法信息并对其进行调用的操作:

//获取类的方法信息:可以使用以下方法获取类的方法信息Method[] methods1 = clazz.getMethods();// 获取所有方法, 不包括私有方法Method[] methods = clazz.getDeclaredMethods(); // 获取所有方法,包括私有方法Method method = clazz.getDeclaredMethod("changeName", String.class); // 获取指定方法,第二个为方法参数类型的Object result = method.invoke(person1, "wkx"); // 调用方法,instance为方法所属对象,args为方法参数的值
//如果调用的方法的修饰词为private,就也要暴力反射,.setAccessible(true);

4、java反射用于场景

  1. 插件系统:通过使用反射,可以在应用程序中实现插件系统。应用程序可以在运行时加载和卸载插件,通过反射调用插件中定义的方法,实现动态扩展功能。

  2. 配置文件解析:反射可以用于解析配置文件,例如XML或JSON文件。通过反射,可以动态地读取配置文件中的类名、字段和方法,并在运行时创建相应的对象。

  3. 单元测试:在单元测试中,反射可以用于访问私有方法和字段,以便进行更全面的测试。通过反射,可以绕过访问修饰符的限制,调用私有方法或设置私有字段的值。

  4. 动态代理:反射可以用于实现动态代理。通过反射,可以在运行时创建代理对象,并在代理对象的方法调用前后执行额外的逻辑,例如日志记录、性能监控等。

  5. 框架开发:许多框架(如Spring)使用反射来实现依赖注入、AOP(面向切面编程)等功能。通过反射,框架可以在运行时动态地创建对象、调用方法,并实现解耦和灵活性

        需要注意的是,虽然反射提供了一种强大的机制来操作类的成员,但过度使用反射可能会导致性能下降和代码可读性降低。因此,在使用反射时应谨慎考虑其适用性和性能影响。


http://www.ppmy.cn/news/1009429.html

相关文章

MongoDB SQL

Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。C:\Users\Administrator>cd C:\MongoDB\Server\3.4\binC:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin>net start MongoDB 请求的…

第七章:进程间通信(IPC)——构成进程间通信的信道方案

系列文章目录 文章目录 系列文章目录前言进程间通信介绍进程间通信目的进程间通信发展进程间通信分类进程通信的原理 管道什么是管道pipe管道通信特点简单设计 命名管道什么是命名管道mkfifostrcmp/strncasecmpunlinkgetch简单设计 共享内存什么是共享内存shmget/ftokipcsshmct…

程序环境和预处理(含C语言程序的编译+链接)--2

文章前言&#xff1a; 上章我们把 程序的翻译环境 程序的执行环境 C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符 #和##的介绍 的相关知识进行了梳理讲解&#xff0c;接下来被把剩余知识 命令定义 …

android studio 实用插件推荐

本文字数&#xff1a;&#xff1a;2352字 预计阅读时间&#xff1a;8分钟 背景 现在做安卓开发的同学基本都是用 Android Studio 了吧&#xff0c;它具有强大的开放性&#xff0c;可以让用户根据自己的需求开发或使用一些插件辅助自己搬砖&#xff0c;当然开发插件我们可能还没…

2023年中小型企业如何选择CRM?

随着科技的不断发展&#xff0c;CRM软件已经成为企业管理的重要工具之一。但是对于中小企业来说&#xff0c;选择一款适合自己企业的CRM软件并不容易。2023年有哪些适合中小企业的crm软件推荐&#xff1f;下面3款crm让企业轻松管理客户&#xff0c;提升企业效率。 1.Zoho CRM …

AWS Amplify 部署node版本18报错修复

Amplify env&#xff1a;Amazon Linux:2 Build Error : Specified Node 18 but GLIBC_2.27 or GLIBC_2.28 not found on build 一、原因 报错原因是因为默认情况下&#xff0c;AWS Amplify 使用 Amazon Linux:2 作为其构建镜像&#xff0c;并自带 GLIBC 2.26。不过&#xff0c;…

2023-08-05 LeetCode每日一题(合并两个有序链表)

2023-08-05每日一题 一、题目编号 21. 合并两个有序链表二、题目链接 点击跳转到题目位置 三、题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例1&#xff1a; 示例2&#xff1a; 示例3&#xff1a; …

搞懂内存大小及计算机类的内存占用

Ubuntu 64位系统下编译32位C可执行文件 步骤1&#xff1a;命令行安装这个支持多编译的包 sudo apt-get install gcc-multilib g-multilib步骤2&#xff1a;g编译的时候加上 -m32 参数 g -m32 heheda.cpp -o heheda运行&#xff1a;./heheda 时就是32位的了 &#xff08;一&…