反射浅析

  • 普通的开发流程是已知对象来获取属性
  • 而反射的流程是——已知属性来获取对象
但我认为反射本身比较抽象

可能是我一开始学Java基础没打好的原因,在学习到框架的时候。就感觉很吃力,学习流于形式。知其然,但不知其所以然。忘的比学的快。到最后还是得反过来啃下反射这块硬骨头。

反射机制

  1. 反射机制允许程序在执行期借助于ReflectionAPI取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到
  2. 加载完类之后,在堆中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了类的完整结构信息。通过这个对象得到类的结构。这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以,形象的称之为:反射
  • p对象--》类型Person类
  • Class对象cls --->类型Class类
如果只是简单的了解反射有什么用,最常见的其实就两个
  • 根据类名创建实例(类名可以从配置文件读取,不用new,达到解耦)
  • 用Method.invoke执行方法

下面java代码的全部流程,我将大体的给大家理顺一下

反射在哪里执行?

其中反射就英语在加载阶段与运行阶段之间

直观展示,上代码,走cmd!

import java.lang.reflect.Method; import java.util.Scanner; public class Test { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Scanner scanner = new Scanner(System.in); System.out.printf("请输入key"); String key = scanner.next(); switch (key) { case "1": Dog dog = new Dog();//静态加载,依赖性很强 dog.cry(); break; case "2": //反射->动态加载 Class cls = Class.forName("Cat"); //加载Person类[动态加载] Object o = cls.newInstance(); Method m = cls.getMethod("hi"); m.invoke(o); System.out.println("ok "); break; default: System.out.println("do nothing.."); } } } class Dog { public void cry() { System.out.printf("汪汪汪"); } }

因为new Dog()是静态加载,因此必须编写Dog
Cat类是动态加载,所以,没有编写Cat类也不会报错,只有当动态加载该类时,才会报错

出现class类说明编译成功

结果如下 说明


我们再追加Cat类的相关信息

class Cat { public void hi() { System.out.printf("喵喵喵"); } }

编译 运行

All in all

1.静态加载:编译时加载相关的类,如果没有则报错,依赖性太强

2.动态加载:运行时加载需要的类,如果运行时不用该类,即使不存在该类,则不报错,降低了依赖性


反射技术

反射的基本的概念

使用反射机制可以动态获取当前class的信息 比如方法的信息、注解信息、方法的参数、属性等;

反射技术应用的场景

  1. JDBC加载驱动连接 class.forname

  2. Spring容器框架IOC实例化对象

  3. 自定义注解生效(反射+Aop)

  4. 第三方核心的框架

反射技术的使用

Class类 代表类的实体,在运行的Java应用程序中表示类和接口

Field类 代表类的成员变量(成员变量也称为类的属性)

Method类 代表类的方法

Constructor类 代表类的构造方法

使用反射机制初始化对象 获取当前class的信息

Class aClass = Class.forName("com.mayikt.entity.UserEntity");

执行无参数构造函数

Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity"); UserEntity userEntity = (UserEntity) aClass.newInstance(); userEntity.setName("mayikt"); userEntity.setUserId(1234); System.out.println(userEntity);

执行有参数构造函数

Class\<?> aClass = Class.forName("com.mayikt.entity.UserEntity"); // 执行有参数构造函数 Constructor<?> constructor = aClass.getConstructor(Integer.class, String.class); UserEntity userEntity = (UserEntity) constructor.newInstance(10, "mayikt"); System.out.println(userEntity);

使用反射机制给属性赋值

Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity"); // 给私有属性赋值 UserEntity userEntity = (UserEntity) aClass.newInstance(); Field userId = aClass.getDeclaredField("userId"); userId.setAccessible(true); userId.set(userEntity,12); Field name = aClass.getDeclaredField("name"); name.setAccessible(true); name.set(userEntity,"mayikt"); System.out.println(userEntity);

  • Exception in thread "main" java.lang.IllegalAccessException: Class com.mayikt.Test001 can not access a member of class com.mayikt.entity.UserEntity with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)

如果使用反射给私有属性或者调用私有的方法 都需要设置权限

使用反射机制给调用方法

Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity"); // 给私有属性赋值 UserEntity userEntity = (UserEntity) aClass.newInstance(); Method meite = aClass.getDeclaredMethod("meite", Integer.class); meite.setAccessible(true); //这一步 暴力反射 Object invoke = meite.invoke(userEntity, 10); S ystem.out.println(invoke);

__EOF__

本文作者飞飞很要强
本文链接https://www.cnblogs.com/LiPengFeiii/p/14879099.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   飞飞很要强  阅读(64)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示