美文网首页Java 杂谈Java开发那些事java进阶干货
Java 为什么对常量的修改没有生效?

Java 为什么对常量的修改没有生效?

作者: 田爽Poison | 来源:发表于2017-05-16 09:44 被阅读0次

写这篇文章的起因是前几天同事改了一个常量类中的提示,发布到测试环境后没有生效,正好看 《Java 解惑(谜题 93: 类的战争)》 提到了这个问题,所以写篇文章记录一下。

以下均使用命令行进行演示,至于为什么没有使用 IDE 后面会提到。

先看一个简单的 Constants 类:

/**
 * Created by Poison on 15/05/2017.
 */
public class Constants {

    public static final String a = "before fixing";

}

再看下 Solution 类:

/**
 * Created by Poison on 15/05/2017.
 */
public class Solution {

    public static void main(String[] args) {
        System.out.println(Constants.a);
    }

}

编译,运行 Solution 的主函数,毫无疑问结果如图:

before fixing

现在我们把 Constants 类修改为:

/**
 * Created by Poison on 15/05/2017.
 */
public class Constants {

    public static final String a = "after fixing";

}

重新编译 Constants 类,再运行 Solution 的主函数,输出结果如图:

after fixing

为什么修改没有生效?是 Constants 类的问题,还是 Solution 类的问题?

我们先反编译 Constants 类看看:

javap Constants

由上图可见,对 Constants 类的修改是生效的。

再看反编译的 Solution 类:

javap Solution

看到这里,原因也就明确了,常量变量会被编译进那些引用它们的类中。这和笔者同事前几日遇到的情况一模一样,同事在本地开发时修改了常量类中的常量字段的值,本地是生效的,原因是因为本地开发使用了 IDE,而 IDE 将引用到常量类的类也重新编译了,所以能看到最新的值,而在发布到测试环境的过程中,打包机仅仅将常量类所属的模块进行了重新编译,未将引用常量的类的模块重新编译,所以当时看见的是更改前的值,同事将常量类的 class 文件反编译后看见的也是修改后的值,但是却忘了看引用该常量类的类,所以当时没有发现这个问题。

Java 解惑
Java 虚拟机规范(Java SE 8版)

更多文章,请访问 田爽Poison

相关文章

网友评论

    本文标题:Java 为什么对常量的修改没有生效?

    本文链接:https://www.haomeiwen.com/subject/ptakxxtx.html