这个绝对是个坑,有时候为了节省时间,图方便,会在服务器直接替换新修改的配置类的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编译器的这个优化特性之后,自然也就能够轻松避免这样的问题。
1
、true
、"Hello"
)或在编译期间能够直接计算出结果的常量表达式(例如:2 * 2
, 5 + 1
, "Hello" + "World"
)。参考文章:https://codeplayer.vip/p/j7thg