起源
最近在调试一个项目的时候发现一个很古怪的问题。现象如下:
定义一个常量类:
public final class Constants {
public static final long LIMIT = 6L;
}
然后另一个类中会引用LIMIT
这个常量。
然后当我将LIMIT=6L -> LIMIT = 3L
时,重新启动springboot
项目时,发现引用LIMIT
的类中,LIMIT
的值还是6,并没有更新成3。
咦???
这个是怎么回事??怎么会没更新呢?
这个不科学啊,后来我尝试把LIMIT
修改为实例变量,然后问题消失。
后来我简单Google
下,发现网上有遇到同样问题。在我阅读的那篇文章中,作者提出一个调用类的常量池的概念。
在编译期就存到了调用类中,那么如果编译的时候和运行的时候A类发生了变化,常量的值变了,在调用类没有重新编译的情况下,调用类就会引用到一个错误常量值。
后来打开idea
编译后的.class
文件,发现调用类引用的常量的确没更新,由此引用了错误的常量值。对于这种情况,需要重新编译调用类。
对于这种问题,由于JVM
优化导致的,遇见着实令人恶心。。。
以后遇到这种莫名其妙的bug
,可以朝着这个思路排查一下。