当前位置: 首页 > news >正文

Java反射面试总结(一)

什么是反射?

Java的反射是指在程序运行时,对于任意一个类,都可以获取到这个类的所有属性和方法,并能够对其进行操作。通过反射机制,可以在程序运行时动态地创建对象、调用方法、获取属性值等。反射可以帮助我们更轻松地实现一些复杂的功能,但也会带来一些性能上的损失。

Java反射机制的基本步骤:

  1. 获取Class对象:通过反射可以动态地获取类对象,即Class对象。Class对象是Java运行时系统中的一个重要概念,每个类都有一个与之对应的Class对象,通过Class对象可以获取类的所有信息。

示例代码:

Class clazz = Class.forName("java.lang.String"); // 获取String类的Class对象
  1. 创建对象:通过Class对象可以实例化一个具体的对象。

示例代码:

Object obj = clazz.newInstance(); // 实例化一个String对象
  1. 访问属性:通过反射可以获取和设置对象的属性,包括公共的和私有的。

示例代码:

Field field = clazz.getField("value"); // 获取value属性
Object value = field.get(strObj); // 获取value属性的值
field.set(strObj, newValue); // 设置value属性的值为newValue
  1. 调用方法:通过反射可以调用对象的方法,包括公共的和私有的。

示例代码:

Method method = clazz.getMethod("substring", int.class, int.class); // 获取substring方法
Object result = method.invoke(strObj, startIndex, endIndex); // 调用substring方法,传递参数startIndex和endIndex
  1. 执行构造函数:通过反射可以调用对象的构造函数来实例化对象。

示例代码:

Constructor constructor = clazz.getConstructor(String.class); // 获取含有一个String类型参数的构造函数
Object obj = constructor.newInstance("Hello, World!"); // 调用构造函数并实例化对象

Java的反射机制带来了很多便利,但同时也会损失一些性能,在使用时需要慎重考虑其是否真正必要。

反射的应用场景了解么?

像咱们平时大部分时候都是在写业务代码,很少会接触到直接使用反射机制的场景。但是!这并不代表反射没有用。相反,正是因为反射,你才能这么轻松地使用各种框架。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。

这些框架中也大量使用了动态代理,而动态代理的实现也依赖反射。

比如下面是通过 JDK 实现动态代理的示例代码,其中就使用了反射类 Method 来调用指定的方法。

public class DebugInvocationHandler implements InvocationHandler {/*** 代理类中的真实对象*/private final Object target;public DebugInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {System.out.println("before method " + method.getName());Object result = method.invoke(target, args);System.out.println("after method " + method.getName());return result;}
}

另外,像 Java 中的一大利器 注解 的实现也用到了反射。为什么你使用 Spring 的时候 ,一个@Component注解就声明了一个类为 Spring Bean 呢?为什么你通过一个 @Value注解就读取到配置文件中的值呢?究竟是怎么起作用的呢?这些都是因为你可以基于反射分析类,然后获取到类/属性/方法/方法的参数上的注解。你获取到注解之后,就可以做进一步的处理。

反射在Java中是一种高级的语言特性,它允许程序在运行时动态地获取类的信息、访问和操作类的属性和方法等。因此,它的应用场景非常广泛,以下是一些例子:

  1. 框架开发:许多框架(如Spring)利用反射获取类的信息和属性,来实现依赖注入、控制反转等功能。

  2. 动态代理:利用反射机制来动态生成代码,从而实现对某些对象的代理。

  3. 注解解析:通过反射来获取类、方法、字段等的注解信息。

  4. Java序列化:反射机制使得可以在编译时未知的情况下,将对象序列化为字节流,然后再通过反射将字节流转换成对象。

  5. 反编译工具:反编译工具利用反射实现对Java代码的分析和探测,可以查看方法、字段的信息以及代码的执行流程等。

总之,反射机制是Java语言中非常有用的一种特性,能够极大地提高程序的可扩展性、灵活性和可维护性。

反射机制的优缺点有哪些?

优点

  1. 动态性:能够运行时动态获取类的信息,访问和操作类的属性和方法,提高了灵活性;例如可与动态编译结合 Class.forName(‘com.mysql.jdbc.Driver.class’),加载MySQL的驱动类;
  2. 适应性:反射机制不依赖于具体的硬件、操作系统和JVM,可以应用于任何Java程序中;
  3. 灵活性:反射机制提供了更灵活的编程方式,可以在不知道具体的类名的情况下,创建对象、调用方法等。

缺点

  1. 性能问题:使用反射性能较低,需要解析字节码,将内存中的对象进行解析。其解决方案是:通过 setAccessible(true) 关闭JDK的安全检查来提升反射速度;
  2. 安全问题:反射机制可以访问和修改对象的私有属性和方法,有可能会破坏程序的安全性和稳定性,因此必须谨慎使用;
  3. 可读性问题:反射机制动态调用方法和属性,代码可读性较差,不容易维护和调试。

总之,优点就是动态获取类信息,操作类的属性和方法们这是核心,缺点无非就是性能、安全和可读性,一定不要死记硬背,要通过原理去理解。

如何获取反射中的Class对象?

  1. Class.forName(“类的路径”);当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。
Class clz = Class.forName("java.lang.String");
  1. 类名.class。这种方法只适合在编译前就知道操作的 Class。
Class clz = String.class;
  1. 对象名.getClass()。
String str = new String("Hello");
Class clz = str.getClass();
  1. 如果是基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象。

除了上述几种种方法,还可以通过ClassLoader类的loadClass()方法来获取Class对象,这种方式常用于加载外部或动态生成的类。

Java反射API有几类?

反射 API 用来生成 JVM 中的类、接口或则对象的信息。

  1. Class 类:反射的核心类,可以获取类的属性,方法等信息。

  2. Field 类:Java.lang.reflect 包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值。

  3. Method 类:Java.lang.reflect 包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。

  4. Constructor 类:Java.lang.reflect 包中的类,表示类的构造方法。

反射使用的步骤?

  1. 获取想要操作的类的Class对象,这是反射的核心,通过Class对象我们可以任意调用类的方法。

  2. 调用 Class 类中的方法,既就是反射的使用阶段。

  3. 使用反射 API 来操作这些信息。

具体可以看下面的例子:

public class Student {private Integer age;public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public static void main(String[] args) {//正常调用Student student = new Student();student.setAge(16);System.out.println("Student Age : " + student.getAge());//使用反射调用try {Class<?> aClass = Class.forName("com.lzl.javaSE.test8.Student");Method setAge = aClass.getMethod("setAge", Integer.class);Constructor<?> studentConstructor = aClass.getConstructor();Object studentObject = studentConstructor.newInstance();setAge.invoke(studentObject, 18);Method getAge = aClass.getMethod("getAge");System.out.println("Student Age : " + getAge.invoke(studentObject));} catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException |IllegalAccessException e) {throw new RuntimeException(e);}}
}

从代码中可以看到我们使用反射调用了 setAge方法,并传递了 16 的值。之后使用反射调用了 getAge 方法,输出其年龄。上面的代码整个的输出结果是:

Student Age : 16
Student Age : 18

从这个简单的例子可以看出,一般情况下我们使用反射获取一个对象的步骤:

  • 获取类的 Class 对象实例
Class<?> aClass = Class.forName("com.lzl.javaSE.test8.Student");
  • 根据 Class 对象实例获取 Constructor 对象
Constructor<?> studentConstructor = aClass.getConstructor();
  • 使用 Constructor 对象的 newInstance 方法获取反射类对象
Object studentObject = studentConstructor.newInstance();

而如果要调用某一个方法,则需要经过下面的步骤:

  • 获取方法的 Method 对象
Method setAge = aClass.getMethod("setAge", Integer.class);
  • 利用 invoke 方法调用方法
setAge.invoke(studentObject, 18);

使用反射拿到私有属性值

Java通过反射机制可以获取和操作类、方法、字段等信息。在Java中,私有属性对外不可见,因此不能直接访问私有属性的值。但是,我们可以使用反射机制来绕过访问限制,获取私有属性的值。

下面是获取私有属性值的示例代码:

import java.lang.reflect.Field;public class PrivateFieldTest {private String privateField = "private value";public static void main(String[] args) throws Exception {PrivateFieldTest obj = new PrivateFieldTest();// 获取私有属性对象Field field = PrivateFieldTest.class.getDeclaredField("privateField");// 设置可访问私有属性field.setAccessible(true);// 获取私有属性值String value = (String) field.get(obj);// 输出私有属性值System.out.println("privateField value: " + value);}
}

在上面的示例代码中,我们首先定义了一个私有属性privateField,然后在main方法中通过反射机制获取privateField的值。这里要注意,我们要通过类的getDeclaredField方法获取私有属性对象,并且要将其设置为可访问状态。

另外,我们还需要调用Field类的get方法获取私有属性的值,其中第一个参数是对象实例,表示要获取该对象中的私有属性值。最后我们将获取到的私有属性值输出。

相关文章:

Java反射面试总结(一)

什么是反射&#xff1f; Java的反射是指在程序运行时&#xff0c;对于任意一个类&#xff0c;都可以获取到这个类的所有属性和方法&#xff0c;并能够对其进行操作。通过反射机制&#xff0c;可以在程序运行时动态地创建对象、调用方法、获取属性值等。反射可以帮助我们更轻松…...

【论文阅读】3D-LaneNet

【论文阅读】3D-LaneNet 主要要做的事情就是 lane detection。这里提一下 BEV&#xff08;Bird‘s Eye View&#xff09; 感知算法&#xff0c;为了将 2D 图像映射到 3D 空间中&#xff0c;能够更准确的检测物体位置&#xff0c;需要 BEV 感知的结果。后续还会继续了解这方面内…...

Kafka的概念|架构|搭建|查看命令

Kafka的概念|架构|搭建|查看命令一 Kafka 概述二 使用消息队列的好处三Kafka 定义3.1Kafka 简介3.2Kafka 的特性3.3 Kafka 系统架构3.4 Partation 数据路由规则四 kafka的架构五 搭建kafka5.1环境准备5.2安装kafka5.3 修改配置文件5.4 编辑其他二台虚拟机的配置文件5.5 编辑三台…...

大数据项目实战之数据仓库:电商数据仓库系统——第5章 数据仓库设计

第5章 数据仓库设计 5.1 数据仓库分层规划 优秀可靠的数仓体系&#xff0c;需要良好的数据分层结构。合理的分层&#xff0c;能够使数据体系更加清晰&#xff0c;使复杂问题得以简化。以下是该项目的分层规划。 5.2 数据仓库构建流程 以下是构建数据仓库的完整流程。 5.2.1 …...

OpenHarmony社区运营报告(2023年3月)

目录 本月快讯 一、代码贡献 二、生态进展 三、社区治理 五、社区活动 六、社区及官网运营 本月快讯 • 《OpenHarmony 2022年度运营报告》于3月正式发布&#xff0c;2022年OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;开源项目潜心务实、深耕发展&am…...

杰林码图像增强算法——超分辨率、图像放大、轮廓和色彩强化算法(二)

一、前言 2023-03-23我发布了基于加权概率模型&#xff08;杰林码的理论模型&#xff09;的图像颜色增强和轮廓预测的应用方法。效果还不太明显&#xff0c;于是我又花了2周的时间进行了技术优化。下面仅提供了x86下的BMP和JPG对应的lib和dll&#xff0c;本文中的算法属于我国…...

在three.js中废置对象

基于three.js子如何废置对象(How to dispose of objects) 前言: 为了提高性能,并避免应用程序中的内存泄露,一个重要的方面是废置未使用的类库实体。 每当创建一个three.js中的实例时,都会分配一定数量的内存。然而,three.js会创建在渲染中所必需的特定对象, 例如几何…...

Java中的String类真的不可变吗?

其实在Java中&#xff0c;String类被final修饰&#xff0c;主要是为了保证字符串的不可变性&#xff0c;进而保证了它的安全性。那么final到底是怎么保证字符串安全性的呢&#xff1f;接下来就让我们一起来看看吧。 一. final的作用 1. final关键词修饰的类不可以被其他类继…...

电脑重装了系统开不了机怎么办?

我们的电脑办公用久后也会出现故障问题&#xff0c;例如卡顿反应慢等等&#xff0c;这时候就要进行重装系统了&#xff0c;但是很多小伙伴重装系统后会出现开不了机的问题&#xff0c;其实我们比较常见的也就是电脑重装系统开不了机的情况。有很多小伙伴反映自己不知道应该怎么…...

SPOJ-NSUBSTR - Substrings(SAM求所有长度子串的最大出现次数)

NSUBSTR - Substrings 题面翻译 你得到了一个最多由 250000250000250000 个小写拉丁字母组成的字符串 SSS。定义 F(x)F(x)F(x) 为 SSS 的某些长度为 xxx 的子串在 SSS 中的最大出现次数。即 F(x)max{times(T)}F(x)max\{times(T)\}F(x)max{times(T)}&#xff0c;满足 TTT 是 S…...

Mariadb10.5基于同服务器多实例主从配置

本次部署环境&#xff1a;Centos8stream 本次部署mariadb版本&#xff1a; mariadb:10.5 本次部署方式&#xff1a;rpm包直接安装&#xff0c;并通过systemd直接托管 可以参考 /usr/lib/systemd/system/mariadb.service 该文件 # Multi instance version of mariadb. For i…...

linux 修改主机名称

1、hostname命令进行临时更改 如果只需要临时更改主机名&#xff0c;可以使用hostname命令&#xff1a; sudo hostname <new-hostname> 例如&#xff1a; 只需重新打开session终端&#xff0c;就能生效&#xff0c; 但是&#xff0c;重启计算机后会回到旧的主机名。…...

学校的地下网站(学校的地下网站1080P高清)

这个问题本身就提得有问题&#xff0c;为什么这么说&#xff0c;这是因为YouTube本身就不是一个视频网站或者说YouTube不是一个传统的视频网站&#xff01;&#xff01;&#xff01; YouTube能够一家独大&#xff0c;可不仅仅是因为有了Google 这个亲爹&#xff0c;还有一点&am…...

勒索病毒是什么?如何防勒索病毒

勒索病毒并不是某一个病毒&#xff0c;而是一类病毒的统称&#xff0c;主要以邮件、程序、木马、网页挂马的形式进行传播&#xff0c;利用各种加密算法对文件进行加密&#xff0c;被感染者一般无法解密&#xff0c;必须拿到解密的私钥才有可能破解。 已知最早的勒索软件出现于 …...

SpringBoot+VUE+Axios 【链接超时】 后端正常返回结果,前端却出现错误无法接收数据

一、错误原因及解决思路 错误提示表明前端发送的请求在默认的 2500ms 超时时间内没有得到服务器的响应&#xff0c;导致请求失败。尝试以下方法来解决这个问题&#xff1a; 增加请求超时时间&#xff1a;可以通过配置 Axios 请求对象的 timeout 属性来增加请求的超时时间&…...

【状态估计】基于增强数值稳定性的无迹卡尔曼滤波多机电力系统动态状态估计(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

快速排序的简单理解

详细描述 快速排序通过一趟排序将待排序列分割成独立的两部分&#xff0c;其中一部分序列的关键字均比另一部分序列的关键字小&#xff0c;则可分别对这两部分序列继续进行排序&#xff0c;以达到整个序列有序的目的。 快速排序详细的执行步骤如下&#xff1a; 从序列中挑出…...

短视频多平台发布软件功能详解

随着移动互联网的普及和短视频的兴起&#xff0c;短视频发布软件越来越受到人们的关注。短视频发布软件除了常规的短视频发布功能&#xff0c;还拥有智能创作、帐号绑定、短视频一键发布、视频任务管理和数据统计等一系列实用功能。下面我们将分步骤详细介绍一下这些功能。   …...

谷歌人机验证Google reCAPTCHA

reCAPTCHA是Google公司推出的一项验证服务&#xff0c;使用十分方便快捷&#xff0c;在国外许多网站上均有使用。它与许多其他的人机验证方式不同&#xff0c;它极少需要用户进行各种识图验证。 它的使用方式如下如所示&#xff0c;只需勾选复选框即可通过人机验证。 虽然简单…...

VB+ACCESS电脑销售系统的设计与实现

为了使此系统简单易学易用、功能强大、软件费用支出低、见效快等特点&#xff0c;我们选择Visual Basic6.0开发此系统。Visual Basic6.0起代码有效率以达到Visual c的水平。在面向对象程序设计方面&#xff0c;Visual Basic6.0全面支持面向对你程序设计包括数据抽象、封装、对象…...

Armv7l或树莓派32位RPI 4B编译faiss

pip3 install faiss-cpu当然找不到预编译的包 手动下载 git clone https://github.com/facebookresearch/faiss.git cd faiss #能需要切换到特定版本标签&#xff0c;例如 v1.7.1&#xff0c;这个版本Cmake 3.18可以过&#xff0c;因为apt install安装的cmake只更新到这里&am…...

嵌入式开发STM32 -- 江协科技笔记

1.背景介绍及基础认知 8大输入输出 斯密特触发器&#xff1a;高于设定阈值输出高电平&#xff0c;低于设定阈值输出低电平 有关上拉输入、下拉输入、推挽输出、开漏输出、复用开漏输出、复用推挽输出以及浮空输入、模拟输入的区别 1、上拉输入&#xff1a;上拉就是把电位拉高…...

8.5 Q1|广州医科大学CHARLS发文 甘油三酯葡萄糖指数累积变化与 0-3期心血管-肾脏-代谢综合征人群中风发生率的相关性

1.第一段-文章基本信息 文章题目&#xff1a;Association between cumulative changes of the triglyceride glucose index and incidence of stroke in a population with cardiovascular-kidney-metabolic syndrome stage 0-3: a nationwide prospective cohort study 中文标…...

Java八股-数据类型转换有哪些?类型互转会有什么问题?为什么用bigDecimal 不用double ?自动装箱和拆箱?包装类?

Java中有哪些数据类型转换&#xff1f; 显示类型转换&#xff1a;在前面一个括号&#xff0c;里面写上要转换的类型 隐式类型转换&#xff1a;小范围的数据类型转大范围的&#xff0c;int到long&#xff0c;float到double 字符串转整形或浮点&#xff1a;整形&#xff1a;In…...

汽配快车道:助力汽车零部件行业的产业重构与数字化出海

汽配快车道&#xff1a;助力汽车零部件行业的数字化升级与出海解决方案。 在当今快速发展的汽车零部件市场中&#xff0c;随着消费者对汽车性能、安全和舒适性的要求不断提高&#xff0c;汽车刹车助力系统作为汽车安全的关键部件之一&#xff0c;其市场需求也在持续增长。汽车…...

Web前端常用面试题,九年程序人生 工作总结,Web开发必看

前端编程&#xff0c;JavaScript 从无知到觉醒 做 Web 开发&#xff0c;离不开 HTML&#xff0c;CSS&#xff0c;JavaScript&#xff0c;尽管日常工作以后台开发为主&#xff0c;但接触的多了&#xff0c;慢慢地理解深入&#xff0c;从只会使用 JS 写函数&#xff0c;发展到使用…...

前端开源JavaScrip库

以下内容仍在持续完善中&#xff0c;如有遗漏或需要补充之处&#xff0c;欢迎在评论区指出。感谢支持&#xff0c;如果觉得有帮助&#xff0c;欢迎点赞鼓励。感谢支持 JavaScript 框架Vue.jsVue.js - 渐进式 JavaScript 框架 | Vue.jsReactReactAngularHome • AngularjQueryj…...

主流Markdown编辑器的综合评测与推荐

根据2025年最新资料&#xff0c;结合功能特性、用户体验和技术适配性&#xff0c;以下是对主流Markdown编辑器的综合评测与推荐&#xff1a; 一、核心对比维度与评估方法 功能完整性&#xff1a;支持数学公式、流程图、代码高亮等复杂格式。跨平台兼容性&#xff1a;Windows/m…...

【OSS】 前端如何直接上传到OSS 上返回https链接,如果做到OSS图片资源加密访问

使用阿里云OSS&#xff08;对象存储服务&#xff09;进行前端直接上传并返回HTTPS链接&#xff0c;同时实现图片资源的加密访问&#xff0c;可以通过以下步骤实现&#xff1a; 前端直接上传到OSS并返回HTTPS链接 设置OSS Bucket&#xff1a; 确保你的OSS Bucket已创建&#xf…...

Android Cameara2 + MediaRecorder 完成录像功能

一、打开相机、预览 打开相机预览流程是Camera2的默认流程 可参考&#xff1a;https://blog.csdn.net/kk3087961/article/details/135616576 二、开启录像功能 开启录像主要包括以下3步&#xff1a; private void startRecording() {// 1. 停止预览并关闭会话if (mCameraSes…...