Java面试重点之反射机制

一、 反射是什么?

允许程序在运行时查询和操作对象的类型信息。通过反射,程序能够在运行时获取对象的类定义信息,如类的名称、方法、字段、注解等,并且可以动态地调用对象的方法或访问其字段,而无需在编译时具体知道对象的类。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。
Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

二、为什么反射机制能实现动态获取?

1. Class对象: 在Java中,每个类都有一个对应的Class对象,可以通过类名或对象实例的getClass()方法获取。Class对象包含了类的结构信息,如类的方法、属性、构造函数等。

2. 获取类的信息: 反射机制允许在运行时通过Class对象来获取类的各种信息,如方法、属性、注解等。通过Class对象的方法,如getMethod()、getField()等,可以获取类的方法、属性等的信息。

3. 调用方法和访问属性: 反射机制允许在运行时动态地调用类的方法、访问类的属性。通过Method对象的invoke()方法,可以调用类的方法;通过Field对象的get()、set()方法,可以访问类的属性。

4. 实例化对象: 反射机制还可以在运行时动态地实例化对象。通过Class对象的newInstance()方法,可以创建类的实例。

三、 反射的用途

很多流行的Java框架,如Spring、Spring Boot和MyBatis等,都广泛使用了反射机制和动态代理。

1. 在Spring和Spring Boot中,通过依赖注入和面向切面编程(AOP),框架能够在运行时动态地管理和配置组件。这通常涉及到在运行时创建对象、调用对象的方法以及处理依赖关系,其中反射机制发挥了关键作用。Spring的核心容器使用反射来实现依赖注入,动态地创建和管理bean。同时,Spring AOP利用动态代理来实现切面的织入,以便在方法调用前后执行额外的逻辑。

2. 在MyBatis中,动态代理也是其实现原理的关键部分。在Mybatis的开发过程中,程序员更加关注 Mapper接口中的方法以及 xxxMapper.xml文件的编写。但是我们仅仅只是写了一个方法名和Sql语句,并且接口是不能被实例化的,那么Mybatis是如何通过 Mapper接口来执行对应的Sql语句呢?

答:MyBatis使用动态代理来创建Mapper接口的实现类,从而避免了手动编写SQL语句和结果集的映射代码。通过动态代理,MyBatis能够在运行时根据Mapper接口的方法动态地生成SQL并执行数据库操作。具体来说,通过 sqlSession.getMapper(UserMapper.class) 方法获取 Mapper 接口的实例时,实际上是通过动态代理生成了一个符合 Mapper 接口定义的实现类,并将其返回给调用者。这样可以在运行时动态地生成 SQL 语句,实现与 Mapper 接口方法的映射,从而将 Mapper 接口与实际的 SQL 实现解耦。
下面是一个简单的示例,演示了如何在MyBatis中使用XML文件定义SQL语句:

(1)创建XML文件:首先,创建一个XML文件,通常以.xml为后缀,用于定义SQL映射。在该文件中,可以定义SQL语句以及参数映射、结果映射等信息。

<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
    <select id="getUserById" resultType="com.example.model.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

(2)创建Mapper接口:然后,创建一个Java接口,用于与XML文件进行关联。该接口中定义的方法名称和XML文件中定义的SQL语句的id相对应。

// UserMapper.java
package com.example.mapper;

import com.example.model.User;

public interface UserMapper {
    User getUserById(int id);
}

(3)配置MyBatis:在MyBatis的配置文件中,通常是mybatis-config.xml,配置MyBatis扫描XML文件的位置,并将其与对应的Mapper接口进行关联。

<!-- mybatis-config.xml -->
```xml
```xml
```xml
```xml

(4)使用Mapper接口:最后,在应用程序中通过MyBatis的SqlSession对象来获取Mapper接口的实例,并调用定义的方法执行SQL语句。

// 使用Mapper接口执行SQL语句
SqlSession sqlSession = ...; // 获取SqlSession对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(123);

3. Java 中的一大利器 注解 的实现也用到了反射。为什么使用 Spring 的时候 ,一个@Component注解就声明了一个类为 Spring Bean 呢?为什么你通过一个 @Value注解就读取到配置文件中的值呢?究竟是怎么起作用的呢?

答:在Spring框架中,@Component注解用于标识一个类作为Spring管理的组件,也就是所谓的Spring Bean。当Spring容器启动时,它会扫描类路径下的所有组件,并根据注解的配置将它们实例化为Bean,然后将它们管理起来。这样,我们就可以在应用程序中通过依赖注入的方式来使用这些Bean。
而@Value注解用于从外部配置文件中读取值,并将这些值注入到标记了该注解的字段或方法参数中。通过在配置文件中设置对应的键值对,Spring在启动时会解析配置文件,并将对应的值注入到使用了@Value注解的位置。

4.JDBC(Class.forName导致类加载)

如果只是希望一个类的静态代码块执行,其它代码不执行,可以使用:

Class.forName("完整类名");

这个方法的执行会导致类加载,类加载时,静态代码块执行。
还有其他用途就不一一列举了。

四、反射的重要类和要注意的问题:

在这里插入图片描述
性能问题: 反射操作通常比非反射代码慢,因为它需要在运行时解析相关的类信息。
安全问题: 使用反射可以访问和修改类的私有成员,这可能会破坏封装性,导致安全隐患。
复杂性: 反射代码通常比直接代码复杂,可能难以阅读和维护。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CarEye 智能叉车管理系统

CarEye 团队在智能车辆管理平台基础上&#xff0c;专门针对叉车管理特殊性开发了叉车管理系统。以下是叉车管理系统的一些主要介绍&#xff1a;

跟TED演讲学英文:Innovating to zero! by Bill Gates

Innovating to zero! Link: https://www.ted.com/talks/bill_gates_innovating_to_zero Speaker: Bill Gates Date: February 2010 文章目录 Innovating to zero!IntroductionVocabularyTranscriptQ&A with Chris AndersonSummary后记 Introduction At TED2010, Bill Ga…

深度学习突破:LLaMA-MoE模型的高效训练策略

在人工智能领域&#xff0c;大模型&#xff08;LLM&#xff09;的崛起带来了前所未有的进步&#xff0c;但随之而来的是巨大的计算资源需求。为了解决这一问题&#xff0c;Mixture-of-Expert&#xff08;MoE&#xff09;模型架构应运而生&#xff0c;而LLaMA-MoE正是这一架构下…

环形链表题

1.环形链表1 看题&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路1&#xff1a;哈希表 遍历所有节点&#xff0c;每次遍历一个节点时&#xff0c;判断该节点是否被访问过。 可以使用哈希表来存储所有已经访问过的节点。每次到达一个节点&#xff0c;如果该节点已…

windows查看nginx是否启动

windows查看nginx是否启动 1.通过命令提示符: 打开命令提示符&#xff08;CMD&#xff09;。您可以通过按下WinR键&#xff0c;然后输入“cmd”并按下Enter键来打开命令提示符窗口。 输入命令 tasklist /fi “imagename eq nginx.exe”。如果命令执行后能看到nginx进程&#x…

【DeepL】菜鸟教程:如何申请DeepL免费API并使用Python的DeepL

前言 在这篇技术博文中,我们将介绍如何利用DeepL的强大功能,通过其免费API在Python项目中实现高质量的文本翻译。我们将从基础开始,解释DeepL是什么,它的用途,如何申请免费API,以及如何在Python中使用DeepL库。 什么是DeepL? DeepL是一个基于人工智能的翻译服务,它以…

RocketMQ MQTT 快速搭建验证

来自业务的需求&#xff0c;需要快速搭建一套支持 MQTT 协议的消息系统。 前期准备&#xff1a; 官方地址&#xff1a;https://github.com/apache/rocketmq-mqtt RocketMQ从4.9.3 版本开始才支持该功能&#xff0c;所以需要先检查 RocketMQ 的版本是否满足。 RocketMQ 部署参…

Java同时使用@RequestBody和@RequestParam传参在postman中执行请求报错:Unsupported Media Type

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Laravel5.4 反序列化

文章目录 0x01 环境搭建0x02 POP 链0x03 exp0x04 总结 前言&#xff1a;CC 链复现的头晕&#xff0c;还是从简单的 Laravel 开始吧。 laravel 版本&#xff1a;5.4 0x01 环境搭建 laravel安装包下载地址 安装后配置验证页面。在 /routes/web.php 文件中添加一条路由&#xf…

神之浩劫2下载教程 MOBA新游神之浩劫2在哪下载/怎么下载

《神之浩劫2Smite 2》重新定义了MOBA游戏的征服模式&#xff0c;为玩家带来更多的互动和进展。最近的开发者深度挖掘展示了游戏地图的全新设计&#xff0c;既简化了基本操作&#xff0c;又丰富了游戏选择。游戏中的敌人也有了新的进展方式。例如&#xff0c;击败火巨人和金之怒…

【深度学习基础(1)】什么是深度学习,深度学习与机器学习的区别、深度学习基本原理,深度学习的进展和未来

文章目录 一. 深度学习概念二. 深度学习与机器学习的区别三. 理解深度学习的工作原理1. 每层的转换进行权重参数化2. 怎么衡量神经网络的质量3. 怎么减小损失值 四. 深度学习已取得的进展五. 人工智能的未来 - 不要太过焦虑跟不上 一. 深度学习概念 先放一张图来理解下人工智能…

powershell 注册全局热键——提升效率小工具

powershell 注册全局热键 01 前言 在处理一些重复工作问题的时候&#xff0c;想搞一个小工具&#xff0c;配合全局快捷键来提高效率。因为是Windows系统&#xff0c;想到C#&#xff0c;但是又不想用VS开发&#xff0c;因为那样不够灵活&#xff0c;没办法随时修改随时用&…

Spring ai 快速入门及使用,构建你自己的ai

第一步&#xff1a;创建springboot项目 jdk必须是17及以上 1.8用不了 第二步 选择web和ai的依赖 选择openai 第三步 需要配置openai key 配置 分享个免费或的apikey的地方New API 会免费赠送1刀的token spring.application.namespringAI spring.ai.openai.base-urlhttps://ap…

推荐一个好用的命令行工具ShellGPT

ShellGPT 配置安装常用功能聊天写命令并执行 高级功能函数调用角色管理 总结 这两天突然想到&#xff0c;现有的很多工具都在被大模型重构&#xff0c;比如诞生了像perplexity.ai 这种新交互形式的搜索引擎&#xff0c;就连wps也推出了AI服务&#xff0c;甚至都可以直接生成ppt…

JavaScript转换和校验数字

本节我们使用的案例还是继续之前的银行家应用程序&#xff0c;只不过我们呢增加了两个账号&#xff0c;代码如下&#xff1a; const account1 {owner: Jonas Schmedtmann,movements: [200, 455.23, -306.5, 25000, -642.21, -133.9, 79.97, 1300],interestRate: 1.2, // %pin…

Leetcode 145:二叉树的后序遍历(迭代法)

给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 思路&#xff1a; 迭代法的思路是&#xff0c;使用栈&#xff0c;一层一层的将树节点遍历入栈。 比如下面这个树&#xff0c;使用迭代法&#xff0c;1&#xff09;第一层&#xff0c;让根节点入栈。2&a…

20240428如何利用IDM下载磁链视频

缘起&#xff1a; https://weibo.com/tv/show/1034:4864336909500449 中国获奖独立纪录片《阿辉》揭秘红灯区“教父”的生存法则 5,751次观看 1年前 发布于 陕西 身为里中横 67.7万粉丝 互联网科技博主 微博原创视频博主 头条文章作者 https://weibo.com/tv/show/1034:4864…

树莓派驱动开发----spi flash设备w25q64开发

这期使用的是spi驱动开发框架&#xff0c;其实spi和iic合起来有一个 Regmap 子系统&#xff0c;下回讲这个&#xff01;&#xff01; 使用方法 &#xff1a;./w25q64App /dev/w25q64-device <cmd> <address> <cnt> <data> ... 可读写擦&#xff0…

代码审计之SAST自动化

前言: 很久没写文章了&#xff0c;有点忙&#xff0c;落个笔&#xff0c;分享一些捣鼓或说适配好的一些好玩的东西。 脚本工具不开源&#xff0c;给一些思路&#xff0c;希望能给大家带来一些收获。 笔者能力有限&#xff0c;如有错误&#xff0c;欢迎斧正。 正文&#xff1a…

文件分块+断点续传 实现大文件上传全栈解决方案(前端+nodejs)

1. 文件分块 将大文件切分成较小的片段&#xff08;通常称为分片或块&#xff09;&#xff0c;然后逐个上传这些分片。这种方法可以提高上传的稳定性&#xff0c;因为如果某个分片上传失败&#xff0c;只需要重新上传该分片而不需要重新上传整个文件。同时&#xff0c;分片上传…