Java基础(10)反射

Java反射是Java语言中的一个功能强大且复杂的机制,它允许程序在运行时访问、检查和修改它本身的结构(类、接口、字段、方法等)。反射机制主要在java.lang.reflect包中定义。

反射的核心组件

  • Class:它的实例表示正在运行的Java应用程序中的类和接口。
  • Field:提供了关于类和接口的字段的信息,以及动态访问字段的方法。
  • Method:提供了关于类和接口的方法的信息,以及用于获取和设置方法的方法(不是打错字)。
  • Constructor:提供了关于类的单个构造函数的信息,以及用于创建类的实例的方法。

反射的基本操作

  1. 获取Class对象:每个类被加载后,JVM就会为其生成一个对应的Class对象,通过它可以访问类的结构信息。

    Class<?> clazz = Class.forName("java.lang.String");
    
  2. 创建实例:可以通过Class对象的newInstance()方法(已过时,建议使用ConstructornewInstance())创建类的实例。

    String str = (String) Class.forName("java.lang.String").newInstance();
    // 推荐方式
    Constructor<String> constructor = String.class.getConstructor(String.class);
    String strInstance = constructor.newInstance("Hello");
    
  3. 访问字段:可以通过Field对象获取或设置类的公有或私有字段。

    Class<?> clazz = Class.forName("java.util.Date");
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {System.out.println("Field: " + field.getName());
    }
    
  4. 调用方法:可以通过Method对象调用类的公有或私有方法。

    Method method = clazz.getMethod("methodName", parameterTypes);
    method.invoke(instance, parameters);
    

深入理解

反射的工作原理与JVM的类加载机制紧密相关。当使用Class.forName()方法时,JVM将指定的类加载到内存中,并返回该类的Class对象。通过这个Class对象,可以访问类的构造函数、方法和字段。

性能考量

虽然反射提供了强大的功能,使得Java程序更加灵活,但它也有一些缺点,尤其是性能方面。反射操作通常比直接的Java方法调用要慢,因为它需要JVM在运行时检查方法、字段和构造函数。此外,反射调用的安全检查也会带来额外的性能开销。

安全性

使用反射可以访问类的私有成员,这在某些情况下可能会破坏封装性,导致安全问题。因此,应谨慎使用反射,尤其是在访问敏感数据时。

示例:使用反射调用私有方法

public class ReflectionTest {private String secretMethod() {return "Secret Message";}public static void main(String[] args) throws Exception {ReflectionTest obj = new ReflectionTest();Class<?> clazz = obj.getClass();Method method = clazz.getDeclaredMethod("secretMethod");method.setAccessible(true); // 使其可访问String message = (String) method.invoke(obj);System.out.println("Message: " + message);}
}

在上面的示例中,我们通过反射调用了ReflectionTest类的私有方法secretMethod。首先,获取ReflectionTest对象的Class实例,然后通过调用getDeclaredMethod获取私有方法的Method实例。由于这是一个私有方法,我们需要调用setAccessible(true)来覆盖Java的访问控制检查。最后,我们通过invoke方法调用它。

反射是Java语言的一个强大特性,但应当谨慎使用,以避免性能问题和安全风险。

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

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

相关文章

【网站项目】高校推免报名

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

K8s: Kubernetes扩展之自定义资源

自定义资源 自定义资源是 K8s 的扩展&#xff0c;有时候需要对K8s进行一个扩展在默认的K8s集群里面提供的资源对象是一个有限的集合比如常用的pod, deployment, service&#xff0c;这些都是K8s原生的资源之所以它资源&#xff0c;是因为它能够对外提供API接口变成一个resourc…

Java-异常处理-定义三角形类Triangle和异常三角形IllegalTriangleException类 (1/2)

任意一个三角形&#xff0c;其任意两边之和大于第三边。当三角形的三条边不满足前述条件时&#xff0c;就表示发生了异常&#xff0c;将这种异常情况定义为IllegalTriangleException类。 自定义异常类IllegalTriangleException&#xff1a; 当三角形的三条边不满足条件&#x…

[随记]Mac安装Docker及运行开源Penpot

下载Docker Desktop for Mac&#xff1a;https://www.docker.com/products/docker-desktop/ 安装Docker Desktop for Mac&#xff0c;安装完成后&#xff0c;启动Docker&#xff0c;然后在终端输入&#xff1a; docker version 在Mac电脑的Desktop&#xff0c;随便创建一个文…

零代码编程:用通义千问免费批量翻译英文文档

首先&#xff0c;在阿里云的dashScope灵积模型服务中&#xff0c;申请一个API-key&#xff0c;有挺多免费token的。 然后&#xff0c;在通义千问中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;现在要完成一个编写基于qwen-turbo模型API和dashscope库的程序脚本…

UML图(总结)

一、静态建模 1、类图: 展现了一组对象、接口、协作和它们之间的关系。 2、对象图 展现了某一时刻一组对象以及它们之间的关系。 3、用例图 展现了用例、参与者(Action)以及它们之间的关系。 二、动态建模 1、序列图&#xff08;顺序图&#xff0c;时序图&#xff09; 描述了以…

Android Handler用法

Android Handler用法 为什么要设计Handler机制&#xff1f;Handler的用法1、创建Handler2、Handler通信2.1 sendMessage 方式2.2 post 方式 Handler常用方法1、延时执行2、周期执行 HandlerThread用法主线程-创建Handler子线程-创建Handler FAQMessage是如何创建主线程中Looper…

云端芳华、运维之美

今天&#xff0c;在我们享受互联网服务带来的便利与高效的同时&#xff0c;有一群人默默地在幕后为我们提供支持&#xff0c;他们就是云端运维人员。 值此五一国际劳动节来临之际&#xff0c;我们要真诚感谢他们辛勤的劳动和奉献&#xff01;

vue2集成ElementUI编写登录页面

目录 1. 整理目录文件: a. app.vue文件如下: b. Login.vue文件如下: c. router/index.js文件如下: d. 删除components中的文件: e. 最终项目目录整理如下: 2. 集成ElementUI编写登录页面 a. 安装ElementUI: b. 在main.js

springcloud自定义全局异常

自行创建一个实体类 /*** 全局异常处理类**/ ControllerAdvice public class GlobalExceptionHandler {ExceptionHandler(Exception.class) ResponseBody public Result error(Exception e){e.printStackTrace(); return Result.fail();}/*** 自定义异常处理方法* param e * re…

MyBatis-plus笔记——分页插件

插件配置 插件配置类&#xff0c;拦截器添加PaginationInnerInterceptor Configuration MapperScan("com.zxb.mp.mapper") // 扫描指定mapper接口路径 public class MyBatisConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisP…

2023-2024年汽车行业报告/方案合集(精选345份)

汽车行业报告/方案&#xff08;精选345份&#xff09; 2023-2024年 来源&#xff1a;2023-2024年汽车行业报告/方案合集&#xff08;精选345份&#xff09; 【以下是资料目录】 2023中国汽车科技50强 2023中国智能汽车产业发展与展望 2023比亚迪海豹汽车拆解报告 2023新能…

unity制作app(3)--gps定位

1.unity中定位Unity之GPS定位&#xff08;高德解析&#xff09;_unity gps定位-CSDN博客 代码需要稍微修改一下&#xff0c;先把脚本绑到一个button上试一试&#xff01; 2.先去高德地图认证&#xff08;app定位&#xff09; 创建应用和 Key-Web服务 API | 高德地图API (ama…

[C++基础学习]----03-程序流程结构之跳转语句详解

前言 在C程序中&#xff0c;跳转语句break和continue是两种用于控制程序流程的关键字&#xff0c;常用于循环语句&#xff08;如for循环、while循环&#xff09;中。 正文 01-简介 1、break关键字&#xff1a; 当程序执行到break语句时&#xff0c;会立即跳出当前所在的循环&…

C#知识|汇总方法重载与静态方法应用技巧

哈喽&#xff0c;你好&#xff0c;我是雷工&#xff01; 今天学习C#方法重载与静态方法应用技巧的相关内容。 01 方法重载有什么好处&#xff1f; 1.1、可以有效的减少类的对外接口&#xff08;只显示一个方法比较简洁&#xff09;&#xff0c;从而降低类的复杂度。 1.2、方便…

【Vue 2.x】学习vue之二组件

文章目录 Vue二组件第五章es6文件导入出1、导出export 组件&#xff08;component&#xff09;1、定义2、模块化与组件化3、组件的分类1、非单文件组件非单文件三步骤创建组件标准写法简化写法组件的嵌套非单文件的不足之处 2、单文件组件vue单文件组件的使用脚手架创建项目重点…

C++@vscode配置C++开发环境常见问题和实践经验

文章目录 abstractvscode配置C/C开发环境常见问题 FAQC/C共用一组tasks.json/launch.json文件?关于配置文件中的注释更快地编译运行调试时调用外部终端控制台二次编译失败问题编译多个源文件&#x1f60a;源文件组织 编译出的可执行文件名中文乱码&#x1f60a;修改tasks.json…

Django框架之视图层

一、三板斧的原理介绍 1、HttpResponse 在Django中&#xff0c;HttpResponse是一个类&#xff0c;用于构建HTTP响应并返回给客户端。当视图函数处理完请求后&#xff0c;需要返回一个响应时&#xff0c;就会使用HttpResponse对象。 &#xff08;1&#xff09;创建HttpRespon…

C语言随笔集

注意 strlen 和 sizeof 的区别 strlen计算的是第一个 ‘\0’ 前面的字符的个数sizeof计算的是占用的内存空间的大小只和定义时有关C语言中,输出double类型(双精度)和float(单精度)时, 编译器默认精确到小数点后六位输出 默认输出的是6位小数,不足6位,以0补齐,超过6位按…

leetcode1329--将矩阵按对角线排序

1. 题意 对角线排序 2. 题解 2.1 直接模拟 跟螺旋输出数组实际上有点像&#xff0c;这里需要枚举对角线数组的起始值。 class Solution { public:void sort_dia(int br, int bc, vector<vector<int>> &mat) {vector<int> tmp;int r mat.size();int…