什么是反射,反射用途,spring哪些地方用到了反射,我们项目中哪些地方用到了反射

news2024/12/30 2:53:37

3分钟搞懂Java反射

一、反射是什么

在Java中,反射(Reflection)是一种强大的工具,它允许程序在运行时获取和操作类、接口、构造器、方法和字段等。反射是Java语言的一个重要特性,它为开发人员提供了许多灵活性,尤其是在构建框架和库时非常有用。

二、获取Class对象的三种方式

1.Class c1 =类名.class

public class MyClass {
    public static void main(String[] args) {
        Class<?> myClass = MyClass.class; // 获取 MyClass 的 Class 对象
        System.out.println(myClass.getName()); // 输出: com.beiyou.example.MyClass
    }
}

2.通过 instance.getClass() 方法,如果你有一个类的实例,你可以调用 getClass() 方法来获取其 Class 对象

public class MyClass {
    public static void main(String[] args) {
        MyClass instance = new MyClass();
        Class<?> myClass = instance.getClass(); // 获取 MyClass 实例的 Class 对象
        System.out.println(myClass.getName()); // 输出: com.beiyou.example.MyClass
    }
}

3.通过 Class.forName() 方法,通过全类名动态加载类,并获取其 Class 对象

public class MyClass {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> myClass = Class.forName("com.example.MyClass"); // 动态加载 MyClass 的 Class 对象
        System.out.println(myClass.getName()); // 输出: com.example.MyClass
    }
}

Java

三、反射的主要用途包括

1.获取类信息:获取类名、包名、父类、接口等。

获取类名:myClass.getName()

获取类的属性:c1.getField(),只能获取public修饰的属性,getDeclaredField(),获取任意修饰符修饰的属性

获取方法:c1.getMethod(),只能获取public的方法,getDeclaredMethodes()获取任意修饰符修饰的方法,

2.创建实例:通过类名或Class对象动态创建实例。

3.访问类成员:获取并操作类的字段、方法和构造器。

也可以使用 Hutool 中的ReflectUtil 类中的方法来操作类的方法和属性。使用Hutool前记得引用Hutool

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.26</version>
</dependency>

例子:首先创建一个基类

import lombok.Data;

@Data
public class Student {
    public int id;
    public String name;
    private int age;

    public Student() {
    }

    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
        System.out.println("这是构造");
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public void say() {
        System.out.println("hello++++++");
    }
    public void eat() {
        System.out.println("吃饭------");
    }
}

测试类test1

import cn.hutool.core.util.ReflectUtil;
import com.beiyou.model.Student;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

@SpringBootTest
class RefleUtilAppTests {

    //创建实例
    Student student = ReflectUtil.newInstance(Student.class, 1, "张三", 18);

    @Test
    void test1() {
        //构造
        Constructor<Student> constructor = ReflectUtil.getConstructor(Student.class);
        // 获取字段
        Field field = ReflectUtil.getField(Student.class, "name");
//        Map<String, Field> fieldMap = ReflectUtil.getFieldMap(Student.class);
        //获取所有字段
        Field[] fields = ReflectUtil.getFields(Student.class);
        //设置字段值
        ReflectUtil.setFieldValue(student, "name", "李四");
        //获取指定字段值
        Object fieldValue = ReflectUtil.getFieldValue(student, "name");
    }
    @Test
    void test2() {
        Student student = ReflectUtil.newInstance(Student.class, 1, "张三", 18);
        // 获取所有方法
        Method[] methods = ReflectUtil.getMethods(Student.class);
        for (Method m : methods) {
            System.out.println(m.getName());
        }
        // 获取指定方法
        Method method = ReflectUtil.getMethod(Student.class, "say");
        System.out.println(method.getName());
        // 执行方法
        ReflectUtil.invoke(student, "say");
    }

}

测试类2

import cn.hutool.core.util.ReflectUtil;
import com.beiyou.model.Student;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


class ReflectionAppTests {
    public static void main(String[] args)   {
        Class<?> studentClass = null;
        try {
            //获取类对象
            studentClass = Class.forName("com.beiyou.model.Student");
            // 获取构造器
            Constructor<?> constructor = studentClass.getConstructor();
            //创建实例
            Object instance = studentClass.newInstance();
            //获取属性
            Field name = studentClass.getField("name");
            name.set(instance, "张三");
            System.out.println("name : " + name.get(instance));
            Field age = studentClass.getDeclaredField("age");
            age.setAccessible(true);
            age.set(instance, 20);
            System.out.println(" age : " + age.get(instance));
        } catch (Exception e) {
           e.printStackTrace();
        }
    }
}

效率:通过new获取对象的操作要比通过反射获取对象速度快得多。根据情况选择使用new还是反射。

四、Spring框架中哪里用到了反射

1. 依赖注入:Spring通常使用反射机制来创建和初始化 Bean。

依赖注入三种方式:构造方法注入,set方法注入和属性注入

2. AOP:代理方式分为动态代理和静态代理,静态代理是我们手写的,动态代理分为Spring动态Spring AOP 使用 JDK 动态代理或者 CGLIB 字节码增强技术来实现 AOP 的切面逻辑,这其中就包含了对被代理对象方法的反射调用。JDK 动态代理适用于实现了接口的目标对象。Spring 使用 java.lang.reflect.Proxy 类来创建代理对象,并且使用 InvocationHandler 接口来定义方法拦截逻辑。

3. MVC 框架:Spring MVC 框架使用反射来调用相应的控制器方法,从而实现请求的处理。

4. 数据库访问框架:Spring 的 JDBC 框架使用反射机制来实现对数据库的访问。

5. 容器管理:Spring 容器也使用了反射机制来管理对象的实例化和依赖注入。

五、我们在项目哪里用到了反射

MyBatis拦截器处理参数时使用,在做WMS仓储系统时,我们的数据表中都有lastUpdatBy这个字段,我们绝大多数业务都需要对lastUpdateBy进行赋值,所以我们就在Mybatis拦截器中通过反射获取参数,然后通过ThreadLocal中的localuser进行统一对其赋值。ThreadLocal为每一个线程提供一个独立的变量副本,使得每个线程在访问变量时获取的都是自己独有的线程副本,ThreadLocal能够实现跨类跨方法实现变量的传递。我们定义了一个LocalUser对象存储在ThreadLocal中,然后就可以获取ThreadLocal中的Localuser对象为lastUpdateBy赋值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2160341.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHP探索校园新生态校园帮小程序系统小程序源码

探索校园新生态 —— 校园帮小程序系统&#xff0c;让生活更精彩&#xff01; &#x1f331;【开篇&#xff1a;走进未来校园&#xff0c;遇见新生态】&#x1f331; 你是否厌倦了传统校园的繁琐与单调&#xff1f;是否渴望在校园里也能享受到便捷、智能的生活体验&#xff1…

APS软件:生产计划排程的秩序守护者

生产计划制定 &#xff08;1&#xff09;APS排程是一种高度精细化的生产计划制定方法&#xff0c;它精准地计算出不同产品不同工序生产任务的起始、结束时间、每段工序加工时间内的生产数量以及产品的整个生产周期&#xff0c;同时全面考量设备性能、人员配置、物料供应等关键…

全球地图——为论文增色

✨全球地图是全球研究常用的结果表现形式&#xff0c;随着学科交叉&#xff0c;很多非地学&#xff08;环境、化学、生物等&#xff09;的顶刊也会运用到全球地图&#xff0c;为结果增色不少 ✨我总结了一些顶刊 (NSP&#xff0c;NG&#xff0c;NC)最新发布的相关图表✨ 这些图…

st7735调试记录

由于该模块陪我已经超过十年&#xff0c;最近想起来学习下lvgl&#xff0c;于是乎将其拿出来&#xff0c;尝试使能该模块从而学会lvgl 第一步肯定是找到资料确定下该模块是否好用。于是到网络上找到如下资料进行验证&#xff1a; https://pan.baidu.com/s/1CEunLuGUqLABR6I0UZ…

结构设计模式 -装饰器设计模式 - JAVA

装饰器设计模式 一. 介绍二. 代码示例2.1 抽象构件&#xff08;Component&#xff09;角色2.2 具体构件&#xff08;Concrete Component&#xff09;角色2.3 装饰&#xff08;Decorator&#xff09;角色2.4 具体装饰&#xff08;Concrete Decorator&#xff09;角色2.5 测试 结…

mysql 报 ERROR 1273: Unknown collation: ‘utf8mb4_0900_ai_ci‘ 的处理

1、数据库sql是mysql8的导出的&#xff0c;本机上安装的还是5.7的版本&#xff0c;然后导入sql&#xff0c;直接就报错。 2、mysql的下载地址&#xff1a; MySQL :: Download MySQL Community Server 3、报错截图&#xff1a; 4、重新选择一个collation就可以了&#xff0c;…

MoNA:复用跨模态预训练模型,少样本模态的福音 | ICML‘24

跨模态转移旨在利用大型预训练模型来完成可能不属于预训练数据模态的任务。现有的研究在将经典微调扩展到跨模态场景方面取得了一定的成功&#xff0c;但仍然缺乏对模态差距对转移的影响的理解。在这项工作中&#xff0c;进行了一系列关于转移过程中源表示质量的实验&#xff0…

最新视频号名字使用规范你了解了吗!

文章来源&#xff1a;视频号官方平台 视频号名字使用需遵循以下规范&#xff1a; 账号名字应当与简介的内容相符&#xff0c;且不得与已注册成功的账号名字重复。 账号超过180天未以视频号身份进行发表、评论等操作&#xff0c;将不再受到名字唯一保护&#xff0c;有其他用户申…

FPGA实现频率、幅度、相位可调的DDS以及DDS Compiler IP核的使用验证

文章目录 一、DDS介绍二、DDS原理2.1 频率计算2.2 相位改变2.3 波形切换 三、Matlab生成波形文件四、FPGA实现DDS4.1 Verilog代码4.2 仿真验证4.2.1 改变频率4.2.2 切换波形4.2.3 相位调节4.2.4 幅度调节 五、Xilinx DDS Compiler的使用5.1 功能框图5.1.1 相位累加器5.1.2 SIN/…

通俗讲解javascript的实例对象、原型对象和构造函数以及它们之间的关系

今天通俗讲解一下js的对象&#xff0c;因为要通俗&#xff0c;所以可能描述不甚准确。 在js中&#xff0c;想要创建一个对象&#xff0c;首先要写出构造函数&#xff08;跟其它的语言不太一样哦&#xff0c;其它语言一般都会先写一个class 类名&#xff09;。 构造函数写法如…

【PGCCC】 复合索引和部分索引,竟然能让查询速度提升 275 倍!

索引对于加速数据库查询和提高 PostgreSQL 应用程序的性能至关重要。但是&#xff0c;并非所有索引都以相同的方式发挥作用。复合索引和部分索引是两种常见类型&#xff0c;每种类型都有不同的用途和对性能的影响。本文我们将深入探讨复合索引和部分索引是什么、它们如何运作以…

关于在vue2中给el-input等输入框的placeholder加样式

::v-deep {.el-input--medium,.el-input__inner {height: 100%;background: #163670;border: 1px solid #4cc0f6;border-radius: 6px 6px 6px 6px;&::placeholder {color: #13EFFF;}} } 效果如下&#xff1a; .el-date-editor .el-range-input{&::placeholder {color:…

SAP MIGO M7146不支持移动原因

移动类型 Z91 查看配置&#xff1a;Z91 匹配的原因没有921 倒是Z92的原因里面有921 那解决方案有2种&#xff0c;但是要根据具体业务要求来 1、审视一下是否移动原因用错了 &#xff1f;换一个移动原因 2、确实是这个移动类型 要用到这个移动原因 &#xff0c;那就在上图 移…

Python编码系列—Python观察者模式:实现事件驱动架构的利器

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

【数字ic自整资料】SV约束constraint

参考链接&#xff1a; SV--随机约束&#xff08;一&#xff09;_sv constraint-CSDN博客 SV--随机约束&#xff08;二&#xff09;_sv constraint f循环-CSDN博客 [SV]Constraint 遇到的问题_父类和子类 constraint-CSDN博客 目录 1、随机化的概念理解 2、约束(constrain…

基于报位时间判断船舶设备是否在线,基于心跳时间判断基站网络是否在线

文章目录 引言I 在线船舶查询在线或者离线船舶显示在线状态统计在线船舶II 树状显示船舶设备数据结构统计船舶设备在线数和总数III 基站网络是否在线IV 知识扩展统计某个key的数据,例如统计船舶分类下的在线船舶MyBatis引言 本文采用的数据库是SQL Server,开发语言为Java。 …

无线协议wlan在华为模拟器中的实现

无线技术 wifi6:标准为802.11&#xff1b; wifi发展趋势&#xff1a; vlan基本概念&#xff1a; wlan组网架构&#xff1a; 1)fat胖AP;能够独立工作&#xff0c;可以单独配置&#xff1b;小型网络使用&#xff0c;功能少&#xff1b; 2)fit瘦APAC&#xff1a;适用大型网络…

《深度学习》—— PyTorch的介绍及PyTorch的CPU版本安装

文章目录 一、PyTorch的简单介绍二、pytorch的CPU版本安装三、 torch、torchvision、torchaudio 三个库的介绍 一、PyTorch的简单介绍 PyTorch是一个由Facebook AI实验室开发的深度学习框架&#xff0c;它基于Python&#xff0c;并提供了高效的GPU加速和灵活的模型定义能力。1…

基于vue框架的传统服饰剪裁交流平台5m953(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,服装分类,服装资讯 开题报告内容 基于Vue框架的传统服饰剪裁交流平台开题报告 一、研究背景与意义 随着全球化进程的加速&#xff0c;文化多样性的保护与传承日益受到重视。传统服饰作为各民族历史文化的瑰宝&#xff0c;不仅承载…

阅读记录:Gradient Episodic Memory for Continual Learning

1. Contribution 提出了一组指标来评估模型在连续数据上的学习情况。这些指标不仅通过测试准确性来表征模型&#xff0c;还通过其跨任务迁移知识的能力来表征模型。针对持续学习任务&#xff0c;提出了GEM模型&#xff08;Gradient Episodic Memory&#xff09;&#xff0c;它…