哈哈,很搞笑的问题吧!可是小编在实际开发中还真的遇到了一个相关的麻烦,敦促我把这个知识点梳理一下。大神可以飘过,小白还真是要了解一下的好。
常量使用目的
1、常量提取出来有利于代码阅读,而且下次再做这种判断不用手写或复制,直接通过常量类就能得到,能够避免有的地方是username,有的地方是name来判断同一个逻辑含义相同变量问题。
不过我觉得提取出来并不会有利于代码性能提升,因为常量分配在内存的常量池中,所以内存不会出现多个相同常量字符串。总的来说提取常量主要是为了避免魔法数字和提高代码可读性。
2、常量定义在 final 的 clas 中,防止被其它类继承和实例化。定义在 interface 中性质也是一样,static final属性。但是 interface 看起来就是会被实现的。
项目场景
小编在做一个三方的业务对接时,业务方要求变更配置好的static final常量。当小编改变定义的常量值之后,遇到这样一个问题,就是将文件上传到服务器上后,发现引用这个常量的代码并没有变成新的值。
这是典型的java常量替换的应用,也是因为不够理解java常量替换的机制导致的问题。
举个小例子:
@Test
public class Test {
String a = "a";
String b = "b";
String str1 = a + b;
String str2 = "a" + "b";
}
以上代码 str2 会在编译时就确定下值来,因为是两个字符串常量的连接值,字符串常量本身就是一个宏变量,而 str2 则不行,因为编译时无法确定 a 与 b 的值,如果把 a 与 b 变量定义为 final 变量,则 str1 就可以在编译时确定值。
修改办法:
其实,只需要将引用该常量新值的 java 文件重新编译成为 class 文件,并上传到服务器上即可。
原理:
当final修饰一个变量时,必须为该变量显示指定初始值,那么这个变量在编译时就可以确定下来,那么这个final变量实质上就是一个“宏变量”,编译器会把程序中所有用到该变量的地方替换成该变量的值。
而宏替换的过程是在java编译中执行的,也就是说 java 文件在编译时就直接将 final 变量替换为对应的值。当我们将final变量所在的 java 源文件编译成 class 文件后,上传到服务器上,但是引用这个 final 变量的 class 文件,依然是在引用旧的 final 变量时编译的,所以才需要将引用新的 final 变量的 class 文件上传到服务器上才可以。
常量定义场景
1、interface中定义常量:接口(Interface)的中变量默认为static final的
public interface ConstantInterface {
String SUNDAY = "SUNDAY";
String MONDAY = "MONDAY";
String TUESDAY = "TUESDAY";
String WEDNESDAY = "WEDNESDAY";
String THURSDAY =