[Java]讲解@CallerSensitive注解

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://blog.csdn.net/m0_69908381/article/details/139726506
出自【进步*于辰的博客】

参考笔记三,P53.1。

1、介绍

大家可能没注意过此注解,我从JDK源码中摘取一段:

@CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)throws NoSuchMethodException, SecurityException {checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);return getConstructor0(parameterTypes, Member.DECLARED);
}

老熟人吧,大家看Reflection.getCallerClass()这个方法,它有什么用?我写个示例:

class C {public static void main(String[] args) {sout getCallerClass();// class C}@CallerSensitivepublic static Class<?> getCallerClass() {return Reflection.getCallerClass();}
}

很显然,这个方法返回调用方(调用类)的 Class 对象。(PS:这个功能在很多时候是用处很大的)

那这其中有什么门道?(@CallerSensitive注解是干什么的)

启发博文:《@CallerSensitive 注解的作用》(转发)。

那位博主已详细说明,我简单总结一下:

JVM认为有些方法敏感或危险(如:Reflection.getCallerClass()),要求调用方法必须使用@CallerSensitive注解注解,且调用方法所属类必须由启动类加载器加载,才能识别此注解。

众所周知,我们自定义的类的类加载器默认是 AppClassLoader(应用程序类加载器),而不是 BootStrapClassLoader(启动类加载器)。

因此,我们可以通过配置VM Options,“假装”类是启动类,令启动类加载器去加载它,便可识别此注解。

2、三种 VM Options

配置命令有三种:

1:-Xbootclasspath:path

表示令JVM从path加载类,用于替换rt.jar

大家可能没注意过rt.jar这个jar包,它里面存放的就是我们平日经常使用的类,如:String、Class。当然,具体来说存放的是class字节码文件。

rt.jar是由启动类加载器加载的,使用此命令的确可以达成目标(“假装”是启动类),但我们不用尝试便可知道使用此命令,JVM一般无法运行。

2:-Xbootclasspath/a:path

表示令JVM将path添加进默认的 Bootstrap 路径(sun.boot.class.path)中,也就是让JVM在加载完rt.jar后加载path中的类。

下面我打印一下sun.boot.class.path参数中的路径:

E:\compile\jdk\java\jdk1.8.371\jre\lib\resources.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\rt.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\jsse.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\jce.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\charsets.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\jfr.jar
E:\compile\jdk\java\jdk1.8.371\jre\classes

再配置命令:-Xbootclasspath/a:G:\projects-local\java\workspace\target\classes,打印结果:

E:\compile\jdk\java\jdk1.8.371\jre\lib\resources.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\rt.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\jsse.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\jce.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\charsets.jar
E:\compile\jdk\java\jdk1.8.371\jre\lib\jfr.jar
E:\compile\jdk\java\jdk1.8.371\jre\classes
G:\projects-local\java\workspace\target\classes

看最后一条。

3:-Xbootclasspath/p:path

表示令JVM优先 Bootstrap 路径加载path。(这条命令一般用得少)

最后,再补充两点:

1path需是编译文件(.class)的存放路径,且是绝对路径,故是.../classes,而不是具体 class 字节码文件。

2:上文说过,自定义类的类加载器默认是 AppClassLoader。我们测试一下:

C.class.getClassLoader();// sun.misc.Launcher$AppClassLoader@18b4aac2

配置 VM Options 后,根据上文所述,此时打印结果应该是xxx.BootstrapClassLoadder,可实际上是null

PS:我暂不知其缘由,猜测可能是Java本身就是这样设计的,就如 BootstrapClassLoader 不是 ExtClassLoader 的父类加载器一般。

最后

这个注解涉及了类加载方面的知识点,如果你有意向学习,推荐一篇博文《一看你就懂,超详细java中的ClassLoader详解》(转发),这也是我系统学习ClassLoader类参考的文章。

如果你对ClassLoader的源码有兴趣,我写了一篇源码解析博文《Java-API简析_java.lang.ClassLoader类(基于 Latest JDK)(浅析源码)》,相信对你有帮助。

本文完结。

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

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

相关文章

micro SD控制——zynq(未完)

文章目录 一、SD基础知识二、SD卡控制器三、文件系统&#xff08;FATFS&#xff09;四、 SD卡控制任务&#xff1a;4.1 txt文本任务&#xff1a;4.1.1 硬件部分&#xff1a;4.1.2 软件部分&#xff1a;1.板级支持包中加入FATFS文件系统2.C设计 一、SD基础知识 1.SD卡的类型、协…

跟着刘二大人学pytorch(第---12---节课之RNN基础篇)

文章目录 0 前言0.1 课程视频链接&#xff1a;0.2 课件下载地址&#xff1a; 1 Basic RNN1.1 复习DNN和CNN1.2 直观认识RNN1.3 RNN Cell的内部计算方式 2 具体什么是一个RNN&#xff1f;3 使用pytorch构造一个RNN3.1 手动构造一个RNN Cell来实现RNN3.2 直接使用torch中现有的RN…

Markdown文档转成微信公众号文章的排版

应用场景 写好Markdown文档&#xff0c;希望将其转成微信公众号文章的排版。希望将自己的文章分享到微信公众号&#xff0c;但不想花太多时间排版&#xff0c;希望通过markdown格式来写文章&#xff0c;然后自动生成微信公众号文章的排版。 解决方案 你的这个问题有很多人已…

Java项目之消息队列(手写java模拟实现mq)【七、⽹络通信协议设计、消息队列服务器端实现、客户端实现】✔ ★

⼗⼀. ⽹络通信协议设计 定义 Request / Response /** 表示一个网络通信中的请求对象. 按照自定义协议的格式来展开的*/ public class Request {private int type;private int length;private byte[] payload;public int getType() {return type;}public void setType(int typ…

简单谈谈云服务器私网IP的存在意义及优势

云服务器是基于虚拟化技术的计算资源&#xff0c;可以在云平台上灵活创建和管理。为了满足不同用户的需求&#xff0c;云服务提供商在云服务器上分配了两种类型的IP地址&#xff1a;公网IP和私网IP。其中&#xff0c;私网IP是指在局域网内使用的内部IP地址&#xff0c;无法通过…

机器学习(V)--无监督学习(二)主成分分析

当数据的维度很高时&#xff0c;很多机器学习问题变得相当困难&#xff0c;这种现象被称为维度灾难&#xff08;curse of dimensionality&#xff09;。 在很多实际的问题中&#xff0c;虽然训练数据是高维的&#xff0c;但是与学习任务相关也许仅仅是其中的一个低维子空间&am…

SpringCloud入门之常用的配置文件 application.yml和 bootstrap.yml区别

1. 加载时机 - bootstrap.yml - 在Spring应用程序启动的早期阶段加载&#xff0c;早于application.yml。 - 它主要用于加载应用程序的上下文或环境设置&#xff0c;例如配置中心的地址、加密解密信息等。 - 通常在ApplicationContext初始化之前加载&#xff0c;因此适用…

环形链表2证明

解法 快慢指针相遇后&#xff0c;其中一个指回头部&#xff0c;然后同步前进 代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNod…

【gitcode】idea 在本地拉取和push本地代码到gitcode仓库

【首次使用】 1、idea 拉取代码&#xff0c;很容易这里就不记录了。 2、push代码时&#xff0c;总是弹窗登录输入在gitcode.com登录能成功。但是在idea 怎么都不成功。控制台提示 remote: HTTP Basic: Access denied fatal: Authentication failed for ******* 认证失败 3…

3D ToF赋能小米CyberDog 2提升视觉灵敏度

随着科技的进步,智能机器人越来越多地融入我们的日常生活。其中,CyberDog 2作为一款前沿的四足机器人,凭借其出色的视觉灵敏度和多功能技术配备,受到了广泛的关注。本文将重点探讨CyberDog 2的视觉系统,尤其是其四种不同类型的摄像头如何共同提升其视觉灵敏度,以及激光传…

uniapp实现路由拦截——遇到问题(三)

uniapp路由拦截开发过程中遇到问题 文章目录 uniapp路由拦截开发过程中遇到问题App 无法退出应用监听返回数据结构解决方式模拟原生物理返回键提示不提示&#xff0c;直接退出应用 微信小程序 登录成功返回页面报错效果图不同平台来源页面数据结构解决方式 App 无法退出应用 安…

HP惠普暗影精灵10 OMEN Gaming Laptop 16-wf1xxx原厂Win11系统镜像下载

惠普hp暗影精灵10笔记本电脑16-wf1000TX原装出厂Windows11&#xff0c;恢复开箱状态oem预装系统安装包&#xff0c;带恢复重置还原 适用型号:16-wf1xxx 16-wf1000TX,16-wf1023TX,16-wf1024TX,16-wf1025TX, 16-wf1026TX,16-wf1027TX,16-wf1028TX,16-wf1029TX, 16-wf1030TX,16-…

Python写UI自动化--playwright的运行模式

Playwright支持两种运行模式&#xff1a;有头模式(Headful) 和 无头模式(Headless)。这两种模式的主要区别在于是否显示浏览器的图形用户界面(GUI)。 目录 有头模式(Headful) 无头模式(Headless) 具体实现步骤 启用无头模式 有头模式&#xff08;默认设置&#xff09; 总…

Autosar诊断-FIM模块功能介绍

文章目录 前言一、FIM模块概述二、FID概念介绍Event ID和DTC之间的关系Event ID与FID之间的关系FIM数据结构三、FiM模块与SW-C模块交互关系四、FIM模块函数调用关系FiM功能模块作用过程前言 Autosar诊断的主体为UDS(Unified Diagnostic Services)协议,即统一的诊断服务,是…

python实战根据excel的文件名称这一列的内容,找到电脑D盘的下所对应的文件位置,要求用程序实现

今天客户需要 根据excel的文件名称这一列的内容&#xff0c;找到电脑D盘的下所对应的文件位置&#xff0c;要求用程序实现 数据样例&#xff1a;记录.xlsx 解决代码&#xff1a; 1、安装必要的库&#xff1a; pip install pandas openpyxl2、编写Python脚本&#xff1a; im…

Modbus为何要转成ProfiNET

Modbus与ProfiNET代表了工业通讯不同阶段的发展&#xff0c;各自具有优缺点。Modbus简单易用&#xff0c;适合小型系统&#xff1b;ProfiNET高效稳定&#xff0c;适用于大型复杂网络。转换Modbus为ProfiNET可提高系统性能和扩展性。实际场景下&#xff0c;升级生产线控制器为Pr…

watch详解

Vue.js中的watch选项允许你监听Vue实例的数据变化&#xff0c;并在数据变化时执行自定义的逻辑。watch的使用场景非常广泛&#xff0c;它可以用来处理诸如数据的验证、异步操作、路由跳转、动画等各种需求。在本文中&#xff0c;我将详细介绍watch的用途以及如何在实际项目中应…

分享一个 .NET Core 使用选项方式读取配置内容的详细例子

前言 在 .NET Core 中&#xff0c;可以使用选项模式&#xff08;Options Pattern&#xff09;来读取和管理应用程序的配置内容。 选项模式通过创建一个 POCO&#xff08;Plain Old CLR Object&#xff09;来表示配置选项&#xff0c;并将其注册到依赖注入容器中&#xff0c;方…

弗洛伊德算法——C语言

弗洛伊德算法&#xff0c;是一种用于解决所有顶点对之间最短路径问题的经典算法&#xff0c;该算法通过动态规划的方法计算出从每个顶点到其他所有顶点的最短路径。 弗洛伊德算法的基本思想是逐步考虑每一个顶点作为中间点&#xff0c;更新所有顶点对之间的最短路径。它通过以…

js 前端 Function.prototype.call.call(0[‘toString‘], *, 16)

这个函数将 数组转任意进制 Function.prototype.call.call(0[toString], *, 16)