4N7JM-CV98F-WY9XX-9D8CF-369TT
java虚拟机编译阶段会将java文件编译程字节码的class文件,编译过程,java虚拟机并不是会原原本本的将java源文件编程class文件,而是会做一些优化;常见有如下:
- java文件中注释代码在编译阶段就会直接丢弃掉;
- 比如会为每一个类生成一个无参的构造函数,
- 如果使用了lombok的@data注解,会自动生成set/get方法等等优化;
- 并发编程中用到的volatile的指令重排其实也是java虚拟机生成class文件的过程中重要的一部分;
而今天我遇到的另外一个问题是java虚拟对常量的优化;先看下java文件,如下图


源文件在212行是引用类型,引用了两个常量相加;而class文件编译后的结果直接是相加之后的局部变量值,为102;
因为不同项目组开发,一个同事将其中一个常量从原来的60改为72,所以变成了102;发现这个bug之后,我就是自然而然的将72改为原来的60,然后开发环境,测试环境全部验完之后,就顺利的更新发布到现网;由于只涉及一个类,所以偷懒不用全量war包更新,走增量更新,将编译后的常量类替换掉;结果测试人员现网验证之后发现还是102;实在找不到原因,只好准备打印log日志观察,在加好日志准备再次增量更新时候竟然发现这里不是变量引用,而是直接变成了局部变量了,所以发现这么隐蔽的问题;其实也是自己对java虚拟机编译过程不熟悉导致的问题;