记一次因为java虚拟机编译阶段对常量的优化导致常量修改后使用增量更新发布现网代码不生效的排查过程

         java虚拟机编译阶段会将java文件编译程字节码的class文件,编译过程,java虚拟机并不是会原原本本的将java源文件编程class文件,而是会做一些优化;常见有如下:

  • java文件中注释代码在编译阶段就会直接丢弃掉;
  • 比如会为每一个类生成一个无参的构造函数,
  • 如果使用了lombok的@data注解,会自动生成set/get方法等等优化;
  • 并发编程中用到的volatile的指令重排其实也是java虚拟机生成class文件的过程中重要的一部分;

     而今天我遇到的另外一个问题是java虚拟对常量的优化;先看下java文件,如下图

记一次因为java虚拟机编译阶段对常量的优化导致常量修改后使用增量更新发布现网代码不生效的排查过程_第1张图片 java源文件

   

记一次因为java虚拟机编译阶段对常量的优化导致常量修改后使用增量更新发布现网代码不生效的排查过程_第2张图片 编译后的class文件

        源文件在212行是引用类型,引用了两个常量相加;而class文件编译后的结果直接是相加之后的局部变量值,为102;

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

你可能感兴趣的:(java虚拟机,编译,常量,现网,增量,java基础)