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

写这篇文章的起因是前几天同事改了一个常量类中的提示,发布到测试环境后没有生效,正好看 《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概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,688评论 0 11
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,767评论 18 399
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,276评论 9 118
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,959评论 6 342
  • 【视觉志】 【雪小禅】 【我看见】 【摄影世界】 【国学精粹与生活艺术】
    湍河故事阅读 195评论 0 2