JVM 编译优化 静态常量会被添加到当前类的“常量池”中,无需加载引用类(常量不加载/常量找不到/常量不更新)

堆、栈和字符串常量池:Java内存管理的核心解析 Java虚拟机(JVM)的内存模型是我们讨论的起点。在这一部分,我们将简要介绍JVM的内存结构,解释堆、栈和字符串常量池在其中的位置和职责。理解这些内存区域在Java程序执行中的角色是深入探讨其工作原理的基础。 阅读详情

标题有点绕,意思是说如果A类中定义了一个常量,且这个常量是一个“编译期常量”,那么当其他类在引用这个常量的时候。A类本身可以不被JVM加载,这个常量可以被直接引用。

是不是更绕了,怎么还多出来一个“编译期常量”。即在编译期即可确定常量值。直接说重点,JVM这个编译优化会引起令人匪夷所思的BUG。让你查也查不到。

还是要回到标题,不加载A类就能直接引用A类的常量。这个常量会被存在调用类的常量池中。这样很容易让我想到既然是在编译期就存到了调用类中,那么如果编译的时候和运行的时候A类发生了变化,常量的值变了,在调用类没有重新编译的情况下,调用类就会引用到一个错误常量值。JVM真的会让这种事发生吗?!

用代码说话:

/**
 * @Author: tiantao
 * @Date: 2019/1/16 10:37 AM
 * @Version 1.0
 */
public class StaticClass {
    static {
        System.out.println("StaticClass loading...");
    }

    public static String VALUE = "static value loading A";

    public static final String FIANL_VALUE = "fianl value loading A";
}
/**
 * @Author: tiantao
 * @Date: 2019/1/16 10:38 AM
 * @Version 1.0
 */
public class StaticClassLoadTest {

    public static void main(String[] args) {
        System.out.println("StaticClassLoadTest...");
        printStaticVar();
    }

    private static void printStaticVar() {

        System.out.println(StaticClass.FIANL_VALUE);

        System.out.println(StaticClass.VALUE);

    }
}

执行结果:

StaticClassLoadTest...
fianl value loading A
StaticClass loading...
static value loading A

说明一下 StaticClass类的FIANL_VALUE是静态常量 而 VALUE 只是静态变量 或者说类变量。

从输出结果可以看出 在打印FIANL_VALUE的时候并没有加载StaticClass类,而是在需要调用到类变量的时候才加载的。

以上只是说明了加载顺序,但是不能说明静态常量 也就是例子中的FIANL_VALUE是被放到了调用类StaticClassLoadTest的常量池中。

接下来我们做如下操作。

1.备份当前的StaticClass的class文件。

2.修改StaticClass

/**
 * @Author: tiantao
 * @Date: 2019/1/16 10:37 AM
 * @Version 1.0
 */
public class StaticClass {
    static {
        System.out.println("StaticClass loading...");
    }

    public static String VALUE = "static value loading B";

    public static final String FIANL_VALUE = "fianl value loading B";
}

执行结果:

StaticClassLoadTest...
fianl value loading B
StaticClass loading...
static value loading B

这个结果毋庸置疑,没毛病。

3.删除现在的StaticClass.class文件

4.将之前备份的StaticClass的副本.class重命名为:StaticClass.class

5.执行程序,看执行结果,见证奇迹:

StaticClassLoadTest...
fianl value loading B
StaticClass loading...
static value loading A

怎么可以这样!

曾经那个修改常量不生效的bug,本地测试怎么都不复现,一上生产死活不生效。我明明没有改调用类,谁知道调用者也要更新!

uniapp - 详细实现移动端公众号 H5 网页授权登录流程及示例代码,申请测试公众号全流程及本地调试无需部署上线服务器就能直接调起微信登陆授权页面,手机移动端h5公众号页面利用微登录拿到用户数据! uni-app,微信公众号,h5网页,uniapp网页端,手机端H5公众号页面,微信网页登陆,uniApp详细实现公众号的登录,微信授权第三方网站登录,流程及逻辑详细教程,OAuth2.0,公众号网页授权,微信网页授权通过code换取网页授权,redirect_url,参数错误,解决,报错,无法调起,如何申请测试公众号,微信公众平台测试号的申请与使用,获取用户openid手机号昵称头像,利用测试号实现本地调试微信登录授权,本地无法调试怎么办,测试公众号,在开发环境下怎么测试,用项目本地ip地址,微信公众号平 阅读详情

相关推荐

C#调用Halcon程序三种方法

C#调用Halcon程序三种方法 1.halcon导出C#文件,在C#里面调用 2.在C#里面使用Halcon引擎调用Halcon程序 3.在C#里面使用Halcon引擎调用.hdev下本地函数或者.hdvp外部函数 Halcon引擎手册:C:/Program Files/MVTec/HALCON-21.11-Progress/doc_en_US/html/manuals/programmers_guide/programmers_guide_0120.html 1.导出C#(代码我只给出类,需要调用)

A541925504的博客 1万+

静态方法什么时候执行?_面试官:知道类在什么时候加载吗?

前言什么情况下会触发类加载的进行呢?本文将结合代码demo谈谈几种情况,希望对大家有帮助。类加载时机什么情况需要开始类加载过程的第一阶段:加载?Java虚拟机规范中并没有进行强制约束,这点可以交给虚拟机的具体实现来自由把握。但是对于初始化阶段,虚拟机规范则严格规定了以下几种情况必须立即对类进行初始化,如果类没有进行过初始化,则需要先触发其初始化。创建类的实例为了验证类加载,我们先配置一个JVM参数...

weixin_39983051的博客 7958

深入解读WT软件湍流强度计算与分析

深入解读WT软件湍流强度计算与分析

weixin_46713695的博客 1020

Java final常量“无法更新”的问题

代码中我们一般都使用一个类统一管理常量,例如: public class AppConst { public static final String STR_1 = "String1"; public static final String STR_2 = "String2"; ...... } ...

weixin_33991727的博客 207

开源工具对比:5款主流大数据脱敏框架评测

数据脱敏(Data Masking/Anonymization),也称为数据漂白、数据去标识化,是指在不影响数据可用性的前提下,通过一定的技术手段对敏感信息进行处理,使其无法被识别或关联到具体个人或实体的过程。当应用程序向数据库写入数据(INSERT/UPDATE)时,ShardingSphere 会拦截 SQL,对配置了脱敏规则的字段,使用指定的算法进行加密/脱敏处理,然后将处理后的数据写入到。如果你的答案是“是”,那么数据脱敏,尤其是针对海量数据的。好的,各位技术同仁,数据安全领域的探索者们,大家好。

小程序开发 1182

华为OD机试真题 新系统 - 8位LED控制器 (Java/Py/C/C++/Js/Go)

本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。

算法大师! 1970

java 静态变量和静态块底层原理

Java静态变量的初始化(static块的本质) 在网上看到了下面的一段代码: public class Test {       static {            _i = 20;        }       public static int _i = 10;              public static void main(String[] args) {

h70614959的专栏 3681

生成模型实战 | VQ-GAN(Vector Quantized-Generative Adversarial Network)

向量量化生成对抗网络 (Vector Quantized-Generative Adversarial Network, VQ-GAN) 结合了向量量化变分子自编码器 (VQ-VAE) 和生成对抗网络 (GAN) 的优势,通过向量量化 (Vector Quantised, VQ) 构建离散潜空间,结合感知损失与对抗损失,在保持语义一致性的同时能够生成纹理细节丰富的图像。在本节中,我们将详细解释 VQ-GAN 的技术原理和各个组成,并使用 PyTorch 从零开始实现 VQ-GAN。

盼小辉丶的博客 6632

java 常量 类加载_面试【JAVA基础】类加载机制

1、类加载过程1.1、加载查找和导入class文件。1.2、链接验证检验载入的class文件的正确性,完整性。准备给类的静态变量分配存储空间,会赋对象类型的默认值。解析将class常量池中的符号引用转换成直接引用。符号引用和直接引用的区别:符号引用:java编译阶段不知道所引用的对象的实际地址,使用符号引用来代替直接引用:能够直接定位到对象的指针,或相对偏移量。能定位到一个对象的内存实际地址。1....

weixin_32139875的博客 704

基于STM32设计的老人防摔倒报警设备(OneNet)_65

本文设计了一种基于STM32单片机的智能老人防摔倒报警设备。该系统结合MPU6050陀螺仪传感器实时监测老人的姿态变化,检测摔倒事件;通过SIM800C通信模块发送短信通知紧急联系人,并将GPS定位信息上传至云端平台,确保家属能够及时了解老人的准确位置。

1万+

① Django手把手从零开发个人博客-前言

手把手教你从零开始玩转手把手教你从零开始玩转Django,全面学习并了解django的运行机制、开发全流程及线上部署。Django,全面学习并了解django的运行机制、开发全流程及线上部署。 专栏介绍 本套教程遵循Django的设计思想,开门见山,快速切入主题,拒绝拖沓,在实战中学习每一个知识点,提高学习的趣味性以及个人成就感,并且能快速将所学运用到实际项目中。 将从零手把手带着你一步步完成博客的每一个功能,通过实现博客文章列表页、文章详情页、作者页面等功能来学习和了解django的视图查询模块相关知.

轻编程的博客 513

static{}语句块详解

声明:转载请注明出处static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法,下面我们详细的讨论一下该语句块的特性及应用。 一、在程序的一次执行过程中,static{}语句块中的内容只被执行一次,看下面的示例:示例一class Test{ public static int X=100; publi

lubiaopan的专栏 2万+

ubuntu linux虚拟机安装部署openclaw详细教程(安装、问题处理)

本文详细介绍了在Ubuntu系统下安装OpenClaw AI助手的完整流程及常见问题解决方案。主要内容包括:1) 通过GIT、Node.js等基础环境配置;2) 使用官方脚本或源码编译两种方式安装OpenClaw;3) 配置向导中的关键选项说明;4) 针对systemctl服务启动失败等常见错误的处理方法。文章特别强调了权限管理、网络依赖和访问配置等易错环节,提供了修改service文件等具体解决方案,帮助开发者顺利完成部署并实现Web UI访问。教程实操性强,适合本地和云服务器环境部署参考。

少说,多做 2029

JVM 常量池汇总

TODO(20240522):这里的意思好像是,类加载后符号引用只是从之前在class静态常量池里的一个东西,变成了运行时常量池里占具体内存的直接引用,但对堆区生成的class对象和方法区的类数据结构,以及符号引用和直接引用的具体表现很模糊。class文件常量池是一个class文件对应一个常量池,而运行时常量池只有一个,多个class文件常量池中的相同字符串只会对应运行时常量池中的一个字符串。String的字面量被导入JVM的运行时常量池时,并不会马上试图在字符串常量池加入对应的String对象,而是。

jiezheee的专栏 1177

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

常量池你了解多少

Java虚拟机(JVM)是一个可以执行Java字节码的虚拟计算机。它是Java平台的核心组成部分,允许Java程序在不同的操作系统和硬件平台上运行。JVM不仅提供了内存管理、垃圾回收等基础服务,还支持多种高级特性,如多线程、安全性和网络通信。常量池是JVM中的一个特殊内存区域,它存储了编译期生成的各种字面量和符号引用。字符串常量(如"Hello, World!")类和接口的全限定名字面量(如数字123或字符’a’)被声明为final的常量值。

无远弗届 1440

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

在java中,常量的定义、常量的存储位置、常量池概念、jvm内存结构、编译期和运行期

《Thinking in java》中这个常量指的是“在Java 中,这类常量必须是原始的 并且以关键字final 表示。在对这个常量进行定义的时候,必须对其进行赋值。 一个既是 static 又是final 的域只占有一份不能改变的存储空间。” 编译期的值的确定“我们不能因为某数据是 final 的就认为在编译期可以知道它的值。在运行期使用随机生成的数值来初始化类的属性,就说明了这一...

dsa572713470的博客 1008

jvm中方法区和常量池详解_深入理解JVM内存分配和常量池

一.虚拟机的构成虚拟结主要由运行时数据区、执行引擎、类加载器三者构成:而我们所说的JVM内存模型指的就是运行时数据区,下面具体分析一下运行时数据区:二.运行时数据区组成和各个区域的作用我们看到运行时数据区可以分为线程共享和线程不共享两部分,其中堆内存和方法区线程共享,本地方法栈、虚拟机栈、程序计数器线程不共享。接下来我们介绍每一个区域的作用:2.1.程序计数器程序计数器(Program Count...

weixin_42299645的博客 1804

JVM调优实战以及常量池详解

【代码】JVM调优实战以及常量池详解。

m0_56437092的博客 366

JVM常量池的前世今生

Java中的常量池,实际上分为两种形态:字符串常量池、静态常量池、运行时常量池。 1.JDK1.7之前,运行时常量池包含(字符串常量池)是存放在方法区,此时方法区的实现是永久带。 2.JDK1.7字符串常量池和静态变量被从方法区拿到了堆中,运行时常量池剩下的还在永久带(方法区)。 3.JDK1.8,永久带更名为元空间(方法区的新的实现),但字符串常量池池还在堆中,运行时常量池在元空间(方法区)。 静态常量池 即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字

mu_IT的博客 233

java当修改final对象、常量值时要重新编译类

一、第一篇转载的文章 当编译final变量时,java编译器通过直接将他们拷贝到使用它们的类中的方式作了优化。这提高了Java应用的速度,但是假如你修改并且重新编译了原始的类,而没有重新编译使用它的类,那么新的值就没有被拷贝过去。 例如,对于两个类ClassA和ClassB: public class ClassA { static public final int P

生活的真相 5324

《剑指JVM》——第8章——类变量和常量——方法区4——运行时数据区篇23

🔥本篇概览:详细讲解了方法区中的类变量和常量,以及JVM设计的哲学——从不变到极速变化。🌈⭕🔥

做一个善良的人,做好自己的事,如果愿意,再发一份光。 1172

再议 String - 字符串常量池与 String.intern() 的应用

>>号外:关注“Java精选”公众号,回复“面试资料”,免费领取资料!“Java精选面试题”小程序,3000+ 道面试题在线刷,最新、最全 Java 面试题!0. Backgr...

Java精选 350

调用常量时,不执行静态代码块

1.编译期常量和运行时常量: 1.1.编译期常量 public static final int A1=2;//编译期就确定A1对应的数值,并把A1的相关引用都会直接替换成其对应的数值2 1.2.运行期常量 public static final int A1="hello".length();//在运行时才能确定具体数值 public class Test { public static void main(String[] args) { System.out.p..

gulanga5的博客 704

再议String-字符串常量池与String.intern()

作者 |GuoMell来源 |blog.youkuaiyun.com/gcoder_/article/details/1066443120. Background在 JAVA 语言中有8中基本类型...

程序猿DD 505

JVM 类加载全过程

梳理了JVM类加载的七个生命周期阶段:加载、验证、准备、解析、初始化、使用和卸载。重点解析了前五个核心阶段:加载阶段读取字节码生成Class对象;验证阶段确保代码安全合法;准备阶段为静态变量分配内存;解析阶段替换符号引用;初始化阶段执行静态赋值和代码块。文章通过类比数据处理流程,形象说明了各阶段作用,并详细阐述了各阶段的工作机制和触发条件,帮助理解JVM类加载原理。

落地 1124

JVM性能优化 —— 类加载器,手动实现类的热加载

Java类加载机制解析 Java类加载过程分为加载、连接和初始化三个阶段。加载阶段将.class文件加载到内存并生成Class对象;连接阶段包括验证、准备和解析;初始化阶段执行类构造器方法。类加载器采用层次结构和双亲委派模式,分为启动类加载器、扩展类加载器和系统类加载器,确保类加载的安全性和唯一性。热部署通过自定义类加载器实现,允许在运行时更新类文件而无需重启应用。热部署与热加载的主要区别在于部署方式和应用场景,前者用于生产环境,后者多用于开发环境。类加载机制是Java反射和动态加载的基础,也是实现热部署的

2301_78843735的博客 1061

24个Jvm面试题总结及答案

1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。 Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。 2...

不喝枸杞的程序员 8915
上一篇: Eclipse生成jar包后,Spring无法扫描到bean定义。
下一篇: 手动释放linux内存cache
天天
博客等级 码龄21年 219粉丝 146原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值