反射机制在项目中的应用场景

面试官:什么是Java反射?它的应用场景有哪些? 反射就是指程序在运行的时候可以知道一个类的自身信息。对于任何一个类:可以知道这个类的属性和方法。对于任何一个对象:可以调用这个对象的任何一个方法和属性。反射就是把java类中的各种成分映射成一个个的Java对象例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行 解剖,把个个 组成部分映射成一个个对象。(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述) 阅读详情

1. 框架开发 (Framework Development)

  • 场景: 框架需要在运行时动态地加载类、创建对象、调用方法,而不需要在编译时知道这些信息。

  • 例子:Spring Framework 的依赖注入 (Dependency Injection)

    Spring 框架使用反射来实现依赖注入,在运行时动态地将依赖对象注入到目标对象中。

    // 示例代码(简化版,仅用于说明原理)
    
    // 自定义注解
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Autowired {}
    
    // 待注入的类
    public class MyService {
        @Autowired
        private MyRepository repository; // 需要注入的依赖
    
        public void doSomething() {
            repository.saveData("Hello, Reflection!");
        }
    }
    
    // 依赖类
    public class MyRepository {
        public void saveData(String data) {
            System.out.println("Saving data: " + data);
        }
    }
    
    // 实现依赖注入的类
    public class DIContainer {
        public static void inject(Object obj) throws Exception {
            Class<?> clazz = obj.getClass();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(Autowired.class)) {
                    field.setAccessible(true); // 允许访问私有字段
                    Class<?> fieldType = field.getType();
                    Object dependency = fieldType.newInstance(); // 创建依赖对象
                    field.set(obj, dependency); // 注入依赖对象
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
            MyService service = new MyService();
            DIContainer.inject(service); // 注入依赖
    
            service.doSomething(); // 调用 service 方法
        }
    }
    
    • 解释:
      • @Autowired 注解用于标记需要注入的字段。
      • DIContainer.inject() 方法使用反射来遍历类的所有字段,找到带有 @Autowired 注解的字段,然后创建依赖对象,并将依赖对象注入到目标对象中。
      • 通过这种方式,MyService 类不需要手动创建 MyRepository 对象,而是由 DIContainer 动态地注入。
    • 好处:
      • 降低了组件之间的耦合度,提高了代码的可维护性和可测试性。
      • 可以在运行时动态地配置组件之间的依赖关系。
  • 例子:MyBatis 的 SQL 映射

    MyBatis 使用反射来将数据库查询结果映射到 Java 对象。

    // 示例代码(简化版,仅用于说明原理)
    
    // 数据库查询结果
    Map<String, Object> row = new HashMap<>();
    row.put("id", 1);
    row.put("name", "John Doe");
    row.put("email", "john.doe@example.com");
    
    // Java 对象
    public class User {
        private int id;
        private String name;
        private String email;
    
        // Getter 和 Setter 方法 (省略)
    }
    
    // 使用反射将数据库查询结果映射到 Java 对象
    public class ObjectMapper {
        public static <T> T mapRowToObject(Map<String, Object> row, Class<T> clazz) throws Exception {
            T obj = clazz.newInstance(); // 创建对象
    
            for (Map.Entry<String, Object> entry : row.entrySet()) {
                String columnName = entry.getKey();
                Object columnValue = entry.getValue();
    
                String methodName = "set" + Character.toUpperCase(columnName.charAt(0)) + columnName.substring(1); // 构造 Setter 方法名
                try {
                    Method method = clazz.getMethod(methodName, columnValue.getClass()); // 获取 Setter 方法
                    method.invoke(obj, columnValue); // 调用 Setter 方法
                } catch (NoSuchMethodException e) {
                    // 如果没有对应的 Setter 方法,则忽略
                }
            }
    
            return obj;
        }
    }
    
    • 解释:
      • ObjectMapper.mapRowToObject() 方法使用反射来遍历数据库查询结果的每一列,并根据列名构造 Setter 方法名。
      • 然后,使用 clazz.getMethod() 方法获取对应的 Setter 方法,并使用 method.invoke() 方法调用 Setter 方法,将数据库查询结果的值设置到 Java 对象中。
    • 好处:
      • 实现了数据库表与 Java 对象的映射,简化了数据访问代码的编写。
      • 可以在运行时动态地映射不同的数据库表和 Java 对象。

2. 序列化和反序列化 (Serialization and Deserialization)

  • 场景: 需要将 Java 对象转换为字节流,以便进行网络传输或持久化存储。 在反序列化时,需要将字节流转换为 Java 对象。

  • 例子:自定义序列化/反序列化框架

    // 示例代码(简化版,仅用于说明原理)
    
    // 使用反射实现序列化
    public class Serializer {
        public static String serialize(Object obj) throws Exception {
            Class<?> clazz = obj.getClass();
            StringBuilder sb = new StringBuilder();
            sb.append("{" + clazz.getName() + ":");
    
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                String fieldName = field.getName();
                Object fieldValue = field.get(obj);
                sb.append(fieldName + "=" + fieldValue + ",");
            }
    
            sb.append("}");
            return sb.toString();
        }
    }
    
    // 使用反射实现反序列化
    public class Deserializer {
        public static Object deserialize(String str) throws Exception {
            // (简化处理,假设字符串格式固定)
            String className = str.substring(1, str.indexOf(":")); // 提取类名
            Class<?> clazz = Class.forName(className);
            Object obj = clazz.newInstance(); // 创建对象
    
            // ... (解析字符串,设置字段值) ... // 这里需要更复杂的字符串解析逻辑,并使用反射设置字段值
    
            return obj;
        }
    }
    
    • 解释:
      • Serializer.serialize() 方法使用反射来遍历对象的所有字段,获取字段名和字段值,并将它们拼接成一个字符串。
      • Deserializer.deserialize() 方法使用反射来根据类名创建对象,并解析字符串,将字段值设置到对象中。
    • 好处:
      • 可以灵活地控制序列化和反序列化的过程。
      • 可以处理复杂的对象关系。

3. 单元测试 (Unit Testing)

  • 场景: 需要测试类的私有方法或私有字段,但无法直接访问这些成员。

  • 例子:使用反射来访问私有成员

    import org.junit.jupiter.api.Test;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    import static org.junit.jupiter.api.Assertions.*;
    
    class MyClassTest {
    
        @Test
        void testPrivateField() throws Exception {
            MyClass obj = new MyClass();
            Field privateField = MyClass.class.getDeclaredField("privateField");
            privateField.setAccessible(true); // 允许访问私有字段
            privateField.set(obj, 100); // 设置私有字段的值
    
            assertEquals(100, obj.getPrivateFieldValue()); // 假设 MyClass 有一个 getPrivateFieldValue() 方法用于测试
        }
    
        @Test
        void testPrivateMethod() throws Exception {
            MyClass obj = new MyClass();
            Method privateMethod = MyClass.class.getDeclaredMethod("privateMethod");
            privateMethod.setAccessible(true); // 允许访问私有方法
    
            String result = (String) privateMethod.invoke(obj); // 调用私有方法
    
            assertEquals("Hello from private method", result);
        }
    }
    
    class MyClass {
        private int privateField;
    
        private String privateMethod() {
            return "Hello from private method";
        }
    
        public int getPrivateFieldValue() {
            return privateField;
        }
    }
    
    • 解释:
      • MyClassTest 类使用 JUnit 框架进行单元测试。
      • testPrivateField() 方法使用反射来访问 MyClass 的私有字段 privateField,并设置其值。
      • testPrivateMethod() 方法使用反射来调用 MyClass 的私有方法 privateMethod()。
    • 好处:
      • 可以测试类的内部实现细节,提高测试覆盖率。
      • 可以在不修改原始类代码的情况下进行测试。

4. 动态代理 (Dynamic Proxy)

  • 场景: 需要在运行时动态地创建代理对象,对方法进行增强或拦截。
  • 例子:AOP (面向切面编程)

AOP 是一种编程范式,用于将横切关注点(例如日志记录、安全检查、事务管理)从核心业务逻辑中分离出来。 Java 动态代理可以用来实现 AOP。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 接口
interface MyInterface {
    void doSomething();
}

// 实现类
class MyClass implements MyInterface {
    @Override
    public void doSomething() {
        System.out.println("MyClass is doing something...");
    }
}

// 动态代理
class MyInvocationHandler implements InvocationHandler {
    private Object target; // 被代理的对象

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method: " + method.getName()); // 前置增强
        Object result = method.invoke(target, args); // 调用原始方法
        System.out.println("After method: " + method.getName()); // 后置增强
        return result;
    }
}

// 示例代码
public class DynamicProxyExample {
    public static void main(String[] args) {
        MyInterface target = new MyClass(); // 创建目标对象
        MyInvocationHandler handler = new MyInvocationHandler(target); // 创建调用处理器

        // 创建代理对象
        MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
                MyInterface.class.getClassLoader(),
                new Class[] {MyInterface.class},
                handler
        );

        proxy.doSomething(); // 调用代理对象的方法,会被拦截
    }
}
  • 解释:
    • MyInvocationHandler 类实现了 InvocationHandler 接口,用于拦截方法的调用。
    • Proxy.newProxyInstance() 方法使用反射来创建代理对象。
    • 当调用代理对象的方法时,实际上会调用 MyInvocationHandler.invoke() 方法,可以在该方法中进行增强或拦截。
  • 好处:
    • 实现了横切关注点与核心业务逻辑的分离,提高了代码的可维护性和可重用性.
    • 可以在运行时动态地添加或删除切面。
全网详细解决Client does not support authentication protocol requested by server;consider upgrading Mysql c 全网详细解决1251 - Client does not support authentication protocol requested by server; consider upgrading Mysql client。 阅读详情

相关推荐

ADG同步性能优化:如何正确配置standby redolog避免WAIT_FOR_LOG状态

本文深入剖析了Oracle ADG(Active Data Guard)同步中常见的WAIT_FOR_LOG状态,指出其根源在于Standby Redo Log(SRL)配置不当。文章提供了从诊断到优化的完整实践指南,重点阐述了SRL大小匹配、组数充足等黄金配置法则,帮助架构师从根本上避免同步延迟,实现稳定高效的实时数据同步。

weixin_29200485的博客 334

反射详解&使用场景

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.以上的总结就是什么是反射反射就是把java类中的各种成分映射成一个个的Java对象。

qq_43842093的博客 4022

SAP FICO会计凭证过账接口

-------------------------------------增加职能范围-ZHANGZG-2022.09.07 注释掉-2022.09.20。CONCATENATE '总账' ls_doc_item-hkont '要求输入成本对象值!*-------------------------------------增加职能范围-ZHANGZG-2022.09.07。*-------------------------------------增加职能范围-ZHANGZG-2022.09.07。

dingqing86的专栏 1079

java反射在项目中的使用场景

Java反射在Spring Boot项目中有非常广泛的应用场景,可以用于实现依赖注入、AOP编程、数据库访问、动态代理、配置读取、属性编辑器、注解处理器、方法拦截器等功能

m0_68705273的博客 3065

Cadence Virtuoso IC617:从零构建传输门与反相器的Schematic设计实战

本文详细介绍了使用Cadence Virtuoso IC617进行传输门与反相器Schematic设计的完整流程,包括环境准备、原理图绘制、Symbol创建、仿真验证及实用技巧。通过分步指导和实战经验分享,帮助初学者快速掌握集成电路设计基础,提升EDA工具应用能力。

weixin_29194693的博客 600

oracle 11.2.0.3.0 client下载,oracle64位客户端 Instant Client

oracle64位 客户端安装程序,Instant Client v11.2.0.3.0(64-bit)可以用,bo客户端需要配这个的,所以装了一个,64位操作系统中、不安装Oracle-32bit客户端,方便使用PLSQL Developer(不支持64bit位Oracle客户端)安装教程安装配置instantclient下载后,解压到D:\Oracle\instantclient_11_2(特...

weixin_42573757的博客 4516

Java反射在实际项目中有哪些应用场景?

java反射机制的应用场景

liurenbi的博客 2049

Dify视觉模型节点避坑指南:我用Qwen2.5-VL做OCR识别时踩过的3个坑(及解决方案)

本文分享了使用Dify平台和Qwen2.5-VL视觉模型进行OCR票据识别时遇到的三个常见问题及解决方案,包括文件变量传递、结构化输出和条件分支判断失效。通过实战经验,帮助开发者优化多模态模型在财务自动化中的应用,提升OCR识别精度和效率。

weixin_29284885的博客 404

反射简介和应用场景

反射的简介

qq_43133294的博客 4258

银行卡密码键盘 SM4 ECB模式+ANSI X9.8 格式标准(带主账号信息)PIN 加解密示例

文章目录1.软加解密示例2.知识点①ANSI X9.8 格式标准②主密钥,工作密钥加解密基本概念:加密种类:3.密码键盘操作4.工具 1.软加解密示例 ————————————————————————————————————————————------ 已知数据: 银行测试主密钥TMK: 1234567890ABCDEFABCDEF0987654321 通过签到接口得到: 工作密钥密文KeyVal...

老孟嘚吧嘚 6653

YOLOv11架构革新:华为VanillaNet与BiFPN深度融合的突破性改进实战指南

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有!

LXY_LOVE36的博客 136

Java反射机制的理解和在项目中的应用场景

Java反射机制的理解 Java程序中的对象在运行时可以表现为两种类型,即编译时类型和运行时类型。例如 Person p = new Student(); ,这行代码将会生成一个p变量,该变量的编译时类型为Person,运行时类型为Student。 有时,程序在运行时接收到外部传入的一个对象,该对象的编译时类型是Object,但程序又需要调用该对象的运行时类型的方法。这就要求程序需要在运行时发现对象和类的真实信息,而解决这个问题有以下两种做法: 第一种做法是假设在编译时和运行时都完全知道类型的具体信息,

冰蛙 1532

osgPython

osgPython是一组 Python 模块,为 OpenSceneGraph 的 C++ 库提供了完整的 Python 接口。这意味着你可以在 Python 中调用几乎所有的 OSG 功能,从创建简单的场景到复杂的渲染效果。核心优势开发速度快:Python 语法简洁,无需编译,快速迭代易于学习:比 C++ 更易上手,适合原型开发和教学生态丰富:可以结合 NumPy、Matplotlib 等科学计算库跨平台:与 OSG 一样支持 Windows、Linux、macOS性能考虑。

深之JohnChen的专栏 454

反射机制及应用场景

1、反射:动态获取信息或动态调用对象的方法的机制。对于任意一个类,都能知道他的所有属性与方法,对于任意对象,都可以获取对象的方法。 应用场景:在第三方应用开发过程中,如果某一个类的方法属性是私有的,或者只对应用系统开放,可以通过反射机制获得自己所需要的信息。 实现方式:1)调用运行时类本身的.class属性 2)利用运行时类的...

weixin_40683982的博客 2144

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

第三篇--Java反射机制

反射机制介绍 JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。 获取 Class 对象的四种方式 如果我们动态获取到这些信息,我们需要依靠 Class 对象。Class 类对象将一个类的方法、变量等信息告诉运行的程序。Java 提供了四种方式获取 Class 对象: 1.知道具体类的情况下可以使用: Class alunbarClass = T

sanku3625的博客 164

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java笔记--反射机制一

通过Java语言中的反射机制可以操作字节码文件(读和修改字节码文件),操作代码片段。java.lang.Class:代表整个字节码,整个类。java.lang.reflect.Method:代表字节码中的方法字节码,代表类中的方法。java.lang.reflect.Constructor:代表字节码中的构造方法字节码,代表类中的构造方法。java.lang.reflect.Field:代码字节码中的属性字节码,代表类中的成员属性。示例: 获取Class的三种方式 要想要操作一个类的字节码,首先要获取到这个

qq_46653910的博客 259

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

反射机制讲解,js和java反射机制的区别。

JAVA为什么要用反射创建对象_为什么几乎所有的Java框架都要用到反射机制,她的魅力在哪里?..._18903290970的博客-优快云博客说起Java的反射机制,大家应该不陌生吧,她是Java语言多态的一种体现。但是在面试过程中,我发现很多人都只是停留在听说过的层面,并没有知其所以然,今天我们就来探讨下。大部分人最早接触的反射代码,是JDBC的那一行Class.forName代码。为什么我们在实际的Java项目中很少用到反射,因为框架都帮我们做掉啦,像Spring、Mybatis、Druid等主流框架

weixin_43416349的博客 466

java反射机制解析

java 反射 定义 功能 示例 概要: Java反射机制详解 | |目录 1反射机制是什么2反射机制能做什么3反射机制的相关API·通过一个对象获得完整的包名和类名·实例化Class类对象·获取一个对象的父类与实现的接口·获取某个类中的全部构造函数 - 详见下例·通过反射机制实例化一个类的对象·获取某个类的全部属性·获取某个类的全部方法·通过反射机制调用某个类的方法·通过反射

who_a_you的博客 315

【面朝大厂】面试官:说一下Java反射机制的应用场景

点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!每天14:00更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细...

weixin_44421461的博客 182

C#中的反射机制的应用type与assembly在项目中的使用

说道C#中的反射机制,我们就必须重点关注type和Assembly两个抽象类的使用。其中Assembly是程序集级别的反射使用,type是类级别的反射使用。下面我们具体从语法用法和实际项目中的应用两个方面来介绍。

河西~石头 1691

ZT java 反射机制

原帖地址:https://www.cnblogs.com/my_life/articles/3118399.html http://www.cnblogs.com/chenliang901114/archive/2013/04/23/javalearner.html http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html htt...

qq_38777611的博客 206

Java 反射机制

参考博文 1、什么是反射? 2、反射的原理 3、反射的优缺点 4、反射的用途 5、反射机制常用的类 6、反射的基本使用

今人不见古时月 110

Java的反射机制

什么是反射 在程序的运行状态中, 可以构造任意一个类的对象, 可以了解任意一个对象所属的类, 可以了解任意一个类的成员变量和方法, 可以调用任意一个对象的属性和方法。 这种动态获取程序信息以及动态调用对象的功能称为 Java 语言的反射机制。反射被视为动态语言的关键。 两种表现类型 Java程序中的对象在运行时可以表现为两种类型,即 编译时类型 运行时类型 例如 User user = new Admin(); 这行代码将会生成一个user变量,该变量的编译时类型为User,运行时类型为Admin。

张三李四王五老六 811

Java反射机制

概述     Java反射机制指的是在Java程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法;对于给定的一个对象,都能够调用它的任意一个属性和方法。这种动态获取类的内容以及动态调用对象的方法称为反射机制。 意义 反射机制极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力。 通过反射机制可以让程序创建和控制任何类的对象,...

Raicho的博客 224

深入理解Java的反射机制与动态代理

1.背景介绍 1. 背景介绍 反射和动态代理是Java中非常重要的概念,它们都涉及到程序在运行时的行为和特性。反射机制允许程序在运行时查询和操作自身的结构,而动态代理则允许程序在运行时动态地创建代理对象来代表其他对象。这两个概念在Java中有着广泛的应用,例如在Spring框架中的AOP编程、Hibernate框架中的代理模式等。 本文将从以下几个方面进行深入探讨: 反射机制的核心概念与...

AI天才研究院 1018
上一篇: Java 注解 (Annotations)的定义和使用规则
下一篇: Spring Boot 项目中,JDK 动态代理和 CGLIB 动态代理的使用
冰糖心书房
博客等级 码龄15年 6016粉丝 690原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值