带你深入学习“反射”技术

news2024/11/23 0:21:05

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)

💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

在这里插入图片描述

文章目录

  • 1、什么是动态语言,什么是静态语言
  • 2、什么是反射
  • 3、Java 获取 Class 对象的几种方式
  • 4、如何通过反射获取 Java 实例
  • 5、反射有什么优缺点
  • 6、反射的应用场景
  • 7、反射的几个重要的 API
  • 8、什么是“反射爆破”

1、什么是动态语言,什么是静态语言

动态语言和静态语言是编程语言的两种基本类型。

静态语言是指在编译时就已经确定变量的数据类型,一旦确定就不能修改。程序在编译时会进行类型检查,如果存在类型不匹配的情况,编译器会报错。常见的静态语言包括Java、C、C++等。

动态语言是指在运行时才确定变量的数据类型,变量的类型可以随时改变。程序在运行时会进行类型检查,如果存在类型不匹配的情况,程序会抛出异常。常见的动态语言包括Python、JavaScript、Ruby等。

相比而言,静态语言在编译时就能发现类型错误,避免了一些常见的错误,但是编写起来比较繁琐。而动态语言则更加灵活,编写起来比较简单,但是容易出现类型错误。不同的编程语言都有自己的优缺点,开发者可以根据实际需求选择合适的语言。

2、什么是反射

反射是动态语言的关键,更是Java语言的一个重要特性,它允许程序在运行时动态地获取类的信息并操作对象。通过反射,程序可以在运行时获取类的构造器、方法、字段等信息,并且可以动态地创建对象、调用方法、修改字段等操作。反射在Java中的应用非常广泛,比如在框架、动态代理、注解、序列化等方面都有重要的作用。但是反射也存在一定的性能问题,因为它需要在运行时进行动态的类型检查和方法调用,所以会带来一定的性能损失。因此,在使用反射时需要谨慎考虑性能问题,避免滥用反射导致程序性能下降。

下面是一个类获取实例的正常方式和反射方式,反射方式就是和正常方式反着来。
在这里插入图片描述

3、Java 获取 Class 对象的几种方式

在Java中,获取Class对象的几种方式有以下几种:

  1. 使用Class.forName()方法:该方法可以根据类的全限定名获取该类的Class对象,例如: Class clazz = Class.forName("com.example.Person");

  2. 使用类的class属性:每个类都有一个class属性,可以直接通过类名.class获取该类的Class对象,例如: Class clazz = Person.class;

  3. 使用对象的getClass()方法:每个对象都有一个getClass()方法,可以获取该对象的Class对象,例如: Person person = new Person(); Class clazz = person.getClass();

  4. 使用ClassLoader的loadClass()方法:ClassLoader可以动态加载类,可以通过ClassLoader的loadClass()方法获取该类的Class对象,例如: ClassLoader classLoader = ClassLoader.getSystemClassLoader(); Class clazz = classLoader.loadClass("com.example.Person");

  5. (特殊) 基本类型的封装类Type可以获得 Class<Integer> intclass = Integer .TYPE

以上是获取Class对象的几种常见方式,开发者可以根据实际需求选择合适的方式获取Class对象。

4、如何通过反射获取 Java 实例

下面是一段通过反射的获取实例的案例:

package com.pany.camp.reflect;

import java.lang.reflect.Method;

/**
 *
 * @description:  反射
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-26 8:29
 */
public class ReflectExample {
    public static void main(String[] args) {
        try {
            // 获取类的Class对象
            Class<?> clazz = Class.forName("com.pany.camp.reflect.MyClass");
            // 获取方法
            Method method = clazz.getMethod("myMethod", String.class);
            // 创建对象
            Object obj = clazz.newInstance();
            // 调用方法
            method.invoke(obj, "Hello, World!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class MyClass {

    public void myMethod(String message) {
        System.out.println(message);
    }
}

输出如下:

Hello, World!

Process finished with exit code 0

5、反射有什么优缺点

反射的优点:

  1. 动态性:反射可以在运行时动态地获取和操作类的信息,而不需要在编译时确定。
  2. 灵活性:反射可以在运行时根据需要创建对象、调用方法、修改属性等,具有很高的灵活性。
  3. 通用性:反射可以应用于任何Java类,不需要对每个类都编写特定的代码。

反射的缺点:

  1. 性能问题:反射调用的性能通常比直接调用要低,因为反射需要动态地解析类和方法,这需要额外的时间和资源。
  2. 安全问题:反射可以访问和修改私有属性和方法,这可能会导致安全问题。
  3. 可维护性问题:反射使代码更加复杂,可读性和可维护性可能会受到影响。

因此,在使用反射时需要权衡其优缺点,根据实际情况选择合适的方案。在性能要求高、安全性要求高或者可维护性要求高的场景中,应该尽量避免使用反射。

6、反射的应用场景

反射的应用场景非常广泛,主要包括以下几个方面:

  1. 动态代理:通过反射可以在运行时动态地生成代理类,实现AOP编程,如Spring框架中的AOP功能。
  2. 注解处理器:反射可以用于读取和处理注解信息,如Java EE中的Servlet和JPA注解。
  3. 序列化和反序列化:反射可以用于将对象序列化为字节流或将字节流反序列化为对象,如Java中的ObjectInputStream和ObjectOutputStream类。
  4. 单元测试框架:反射可以用于单元测试框架中的测试用例自动生成,如JUnit框架中的@Test注解。
  5. ORM框架:反射可以用于ORM框架中的实体类和数据库表的映射,如Hibernate框架中的实体类映射。
  6. 动态配置:反射可以用于动态读取和修改配置文件,如Java中的Properties类。

总之,反射是Java语言中非常重要和常用的特性,可以大大提高程序的灵活性和可扩展性。

7、反射的几个重要的 API

Java中的反射机制可以在运行时动态地获取一个类的信息,包括类的属性、方法、构造函数等,并且可以在运行时调用这些属性、方法、构造函数等。反射机制的核心类是java.lang.reflect包下的一些类,下面介绍几个重要的API并用代码说明。

  1. Class类:表示一个类的类型,可以获取类的各种信息。
Class<Person> personClass = Person.class; // 获取Person类的Class对象
System.out.println(personClass.getName()); // 输出类的全限定名
System.out.println(personClass.getSimpleName()); // 输出类的简单名称
Field[] fields = personClass.getDeclaredFields(); // 获取类的所有属性
for (Field field : fields) {
    System.out.println(field.getName()); // 输出属性名
}
Method[] methods = personClass.getDeclaredMethods(); // 获取类的所有方法
for (Method method : methods) {
    System.out.println(method.getName()); // 输出方法名
}
  1. Constructor类:表示一个类的构造函数,可以创建类的实例。
Constructor<Person> constructor = personClass.getDeclaredConstructor(String.class, int.class); // 获取Person类的有参构造函数
Person person = constructor.newInstance("张三", 20); // 创建Person类的实例
System.out.println(person.getName()); // 输出"张三"
  1. Field类:表示一个类的属性,可以获取和修改属性的值。
Field nameField = personClass.getDeclaredField("name"); // 获取Person类的name属性
nameField.setAccessible(true); // 设置属性可访问
nameField.set(person, "李四"); // 修改属性值
System.out.println(person.getName()); // 输出"李四"
  1. Method类:表示一个类的方法,可以调用方法并获取返回值。
Method setNameMethod = personClass.getDeclaredMethod("setName", String.class); // 获取Person类的setName方法
setNameMethod.invoke(person, "王五"); // 调用方法
System.out.println(person.getName()); // 输出"王五"

8、什么是“反射爆破”

“反射爆破”是指利用反射机制来破解密码或者进行恶意攻击的一种技术手段。通常情况下,我们使用反射机制是为了更加灵活地操作类的属性、方法等,但是黑客可以通过反射机制来获取类的私有属性、方法等,从而实现对系统的攻击。比如,黑客可以通过反射机制获取某个类的私有属性,然后通过修改属性值的方式来实现对系统的攻击。因此,在编写程序时,我们应该注意对类的属性、方法等进行适当的封装,避免被反射攻击。同时,我们也应该注意程序的安全性,避免被黑客利用反射机制进行攻击。

class.setAccessible(true)是Java设置后有可能造成“反射爆破”,它可以用于设置类的访问权限。在Java中,类的访问权限分为public、protected、default和private四种。其中,public表示任何类都可以访问,protected表示只有当前类和其子类可以访问,default表示只有同一个包中的类可以访问,private表示只有当前类可以访问。

当我们使用class.setAccessible(true)时,就可以设置当前类的访问权限,使得即使该类的访问权限为private,也可以通过反射机制来访问该类的私有属性、方法等。这种机制虽然可以提高程序的灵活性和可扩展性,但同时也增加了程序的安全风险,因此在使用时需要谨慎,避免被黑客利用反射机制进行攻击。

在这里插入图片描述

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊

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

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

相关文章

Git入门到精通全套教程(涵盖GitHub\Gitee码云)

一个小时搞定Git 对应的视频教程讲解&#xff1a; Git入门到精通全套教程&#xff08;涵盖GitHub\Gitee码云&#xff09;_哔哩哔哩_bilibili 目录 1. 为什么要使用版本控制软件 2. 市场上的版本控制软件 3. Git简介 3.1Git简介 3.2集中式vs分布式 3.3作用 二、Git的使用…

【MySQL基础 | 第二篇】数据处理之分组查询

前言 查询语句属于DML&#xff08;Data Manipulation Language&#xff09;数据操作语言的其中一种&#xff0c;用于从数据库中提取所需的数据。通过灵活的条件和组合&#xff0c;查询语句帮助用户有效地获取、过滤和排序数据&#xff0c;满足各种信息需求。 文章目录 前言1️⃣…

阿里企业邮箱注册申请流程(图文详解)

2023阿里云企业邮箱注册流程&#xff0c;企业邮箱分为免费版、标准版、集团版和尊享版&#xff0c;阿里云百科分享企业邮箱版本区别&#xff0c;企业邮箱收费标准&#xff0c;以及阿里企业邮箱详细注册开通流程&#xff0c;包括阿里云账号注册、实名认证、企业邮箱版本区别及选…

基于Fedora 38的Ultramarine Linux 38推出了System76的调度器

导读Ultramarine Linux 38已经发布&#xff0c;它是另一个基于Fedora Linux的发行版&#xff0c;具有Budgie、GNOME、KDE Plasma和 elementary OS的Pantheon桌面环境的四个版本。 基于Fedora Linux 38&#xff0c;但默认使用Linux内核6.3&#xff0c;Ultramarine Linux 38&…

人工智能的几个概念

一、什么是人工智能 人工智能不是最近几年才兴起的&#xff0c;它已经有几十年发展的历史&#xff0c;下面是业内公认的一种关于人工智能概念的定义&#xff1a;人工智能&#xff08;Artificial Intelligence&#xff09;&#xff1a;缩写为AI&#xff0c;是研究开发用于模拟、…

报名开启!2023大模型应用创新挑战赛来啦

满脑创意无处落地&#xff1f; 满身技术无人看到&#xff1f; 飞桨邀你开启大模型应用创意挑战之旅 寻找那个最具创意的你 资深开发者指导&#xff0c;助你落地“黄金”项目 大模型从业者合作交流 找到创业道路上的partner 高额奖金、技能提升、优质项目 官方扶持落地&#xff…

MCScanX安装与使用

为什么要写这篇文章&#xff1a; 最近因为朋友需要用到MCScanX画两个物种的共线性点图&#xff0c;但是发现搜到的blog中所提供的安装方法都不太相同&#xff0c;且在都会出现或多或少的问题&#xff0c;所以来找我帮忙&#xff0c;我搜到的所有blog安装链接http://chibba.pgml…

Flink的TopN

1.为什么定时器的时间设置为&#xff0c;窗口的end值1ms就可以呢&#xff1f; 因为定时器是下游&#xff0c;水位线是取的多个上游的最小的&#xff0c; 水位线是跟在数据后面的&#xff0c;所以当定时器的时间到达时&#xff0c;上游一定计算完成了&#xff0c;并且数据已经在…

LLM - 搭建 DrugGPT 结合药物化学分子知识的 ChatGPT 系统

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131384199 论文&#xff1a;DrugChat: Towards Enabling ChatGPT-Like Capabilities on Drug Molecule Graphs DrugChat&#xff0c;基…

便携式明渠流量计比对装置的基本要求

便携式明渠流量计比对装置的基本要求有哪些&#xff1f; 符合国标要求中对流量监测单元的比对&#xff08;每2分钟采集一次数据&#xff0c;连续记录 6次数据与在线流量计数据进行液位误差比对&#xff0c;测量10分钟内的流量数据与在线流量计数据进行流量误差比对&#xff09;…

springboot服务时间筛选问题,同一服务部署在本地和Linux服务器,同样的时间筛选数据不一致

项目场景&#xff1a; springboot项目通过时间筛选数据、 问题描述 时间筛选问题&#xff0c;同一服务部署在本地和Linux服务器&#xff0c;同样的时间筛选数据不一致 接收的参数 JsonFormat(pattern "yyyy-MM-dd") private Date queryDate;服务器打印日志出来的…

Linux常用命令——fsck命令

在线Linux命令查询工具 fsck 检查并且试图修复文件系统中的错误 补充说明 fsck命令被用于检查并且试图修复文件系统中的错误。当文件系统发生错误四化&#xff0c;可用fsck指令尝试加以修复。 语法 fsck(选项)(参数)选项 -a&#xff1a;自动修复文件系统&#xff0c;不询…

JavaScript数组遍历的各种方式

目录 第一种方式&#xff08;for循环&#xff09; 第二种方式&#xff08;forEach 遍历&#xff09; 第三种方式&#xff08;for...in&#xff09; 第四种方式&#xff08;for...of&#xff09; 第五种方式&#xff08;map方法遍历&#xff09; 六、性能对比 第一种方式&…

【yolov5系列】将yolov5s模型部署到SigmaStar的9383芯片上

今年年初&#xff0c;接触了星宸科技&#xff08;sigmastar&#xff09;的芯片9383&#xff0c;将深度学习模型进行部署&#xff0c;使用sigmastar的深度学习加速硬件IPU进行模型推理。这里简单记录下sigmastar相关内容。 补充说明&#xff0c;之前使用的是瑞芯微的芯片&#x…

大数据从0到1的完美落地之Flume案例_3

案例演示 案例演示&#xff1a;SyslogtcpMemLogger Syslogtcp: syslog广泛应用于系统日志。syslog日志消息既可以记录在本地文件中&#xff0c;也可以通过网络发送到接收syslog的服务器。接收syslog的服务器可以对多个设备的syslog消息进行统一的存储&#xff0c;或者解析其中…

经济统计类的实证论文解剖

整理来源 UP主&#xff1a;Michaelscholar https://space.bilibili.com/550661456/video 截图 1.读什么文献 国内&#xff1a;中文CSSCI 期刊&#xff1a;中国社会科学&#xff0c;经济研究&#xff0c;经济学&#xff08;季刊&#xff09;&#xff0c;管理世界&#xff0…

MySQL数据库——主从复制

目录 前言一、读写分离概述1. 什么是读写分离&#xff1f;2. 为什么要读写分离呢&#xff1f;3. 什么时候要读写分离&#xff1f;4. 主从复制与读写分离5. mysq支持的复制类型6. 主从复制的工作过程7. MySQL主从复制延迟 二、主从复制配置方法 前言 在实际的生产环境中&#x…

c++ GoogleTest编译使用

编译 1.下载zip源码 2.解压&#xff0c;使用cmake生成工程 第一处填解压生成的文件夹 第二处的build路径可以不存在&#xff0c;点击configure会cmake提示创建 弹出界面中要选择自己的vs版本&#xff0c;选择finish。 然后点击generate&#xff0c;然后点击open Project。 生…

使用kubesphere搭建k8s集群

目录 1准备3台虚拟机 2 每台虚拟机更新yum的软件包&#xff0c;时间设置等 3 关闭防火墙 4 添加三台服务器的域名设置 5 设置三台服务器之间免密 6 安装kubesphere必要依赖&#xff0c;每个节点都要装&#xff0c;不然报错&#xff1a;socat not found in system path 7…

校园广播对讲音柱话筒

校园广播对讲话筒 校园广播对讲话筒&#xff1a;增强校园沟通的利器 提起校园广播对讲话筒&#xff0c;你或许会想到它在紧急情况下的应用。然而&#xff0c;这个功能强大的设备在校园内的广泛运用&#xff0c;不仅仅局限于危机解决。它成为了促进校园内部沟通、加强团队协作…