java编译优化-常量引用替换
常量引用替换
这个绝对是个坑,有时候为了节省时间,图方便,会在服务器直接替换新修改的配置类的class文件。但是往往会出现替换完以后,服务器的war包实际没有生效。这就是因为java编译的自动优化发生了常量引用替换。
当Java编译器编译源代码时,如果发现某处代码引用了「常量」(同时使用static
和final
两个关键字来修饰),且该常量为字面值形式的原始数据类型或字符串,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编译器会在编译源代码时,也会进行优化,会将代码中的常量引用替换为对应的字面值。
- 并不是所有的常量引用都会被替换,该常量必须是原始数据类型或字符串类型,常量的值必须是字面值(例如:
1
、true
、"Hello"
)或在编译期间能够直接计算出结果的常量表达式(例如:2 * 2
,5 + 1
,"Hello" + "World"
)。
注意
- 在应用部署的过程中,尽量不要通过类似的方式来修改配置参数!这种重复的必要性操作是很容易疏忽的,一旦疏忽,就可能给生产环境带来重大损失。我们应该编写程序代码或使用第三方工具,确保依赖于运行环境的参数配置能够自动化智能化的切换,而无需在每次部署时都提心吊胆。
- 上面示例代码中的"theAppId" + "thePassword"实际上也会被 Java 编译器优化合并为一个字符串字面值"theAppIdthePassword"。
参考文章:https://codeplayer.vip/p/j7thg