java编译优化-常量引用替换

常量引用替换

这个绝对是个坑,有时候为了节省时间,图方便,会在服务器直接替换新修改的配置类的class文件。但是往往会出现替换完以后,服务器的war包实际没有生效。这就是因为java编译的自动优化发生了常量引用替换。

当Java编译器编译源代码时,如果发现某处代码引用了「常量」(同时使用staticfinal两个关键字来修饰),且该常量为字面值形式的原始数据类型或字符串,Java编译器会将此处的常量引用优化为常量值的「内联」(inline)。

举个例子:

public class Const {

    /** 请求第三方平台所需的 APP_ID */
    public static final String APP_ID = "theAppId";
    /** 请求第三方平台所需的 APP_KEY */
    public static final String APP_KEY = "thePassword";

}
public class ThirdPartyClient {

    public void postRequest(String args) {
        // Const.APP_ID  的引用 被替换成了该常量在编译时的字符串字面值
        // Const.APP_KEY 的引用 被替换成了该常量在编译时的字符串字面值 
        String text = "theAppId" + "thePassword" + args;
        // handle the text
        // ……
    }

}

在Java中,常量在初始化赋值后是不能再被改变的,因此Java编译器就会针对常量进行优化,从而在运行时避免变量引用的调用开销。

大家了解了Java编译器的这个优化特性之后,自然也就能够轻松避免这样的问题。

小结

  • Java编译器会在编译源代码时,也会进行优化,会将代码中的常量引用替换为对应的字面值。
  • 并不是所有的常量引用都会被替换,该常量必须是原始数据类型或字符串类型,常量的值必须是字面值(例如:1true"Hello")或在编译期间能够直接计算出结果的常量表达式(例如:2 * 2, 5 + 1, "Hello" + "World")。

注意

  • 在应用部署的过程中,尽量不要通过类似的方式来修改配置参数!这种重复的必要性操作是很容易疏忽的,一旦疏忽,就可能给生产环境带来重大损失。我们应该编写程序代码或使用第三方工具,确保依赖于运行环境的参数配置能够自动化智能化的切换,而无需在每次部署时都提心吊胆。
  • 上面示例代码中的"theAppId" + "thePassword"实际上也会被 Java 编译器优化合并为一个字符串字面值"theAppIdthePassword"。

参考文章:https://codeplayer.vip/p/j7thg

posted @ 2021-08-09 10:19  半柠檬  阅读(546)  评论(0编辑  收藏  举报