代码之家  ›  专栏  ›  技术社区  ›  DJClayworth

Java常量的本地缓存

  •  5
  • DJClayworth  · 技术社区  · 14 年前

    假设我有一个Java应用程序,它使用来自库的(静态)int常量:

    int myval=outsideLibraryClass.constant_int;

    现在,在不重新编译我的应用程序的情况下,我在一个稍微不同版本的OutsideLibraryClass上运行它,其中常量int的值是不同的。

    我的应用程序会看到新值(因为它在运行时接收到它)还是旧值(因为该值在我的方法中被编译成字节码)?如果常量int是final,它有什么区别吗?Java规范中有一部分谈到这个吗?

    4 回复  |  直到 14 年前
        1
  •  4
  •   Nulldevice    14 年前

    对常量字段的引用在编译时解析为它们所表示的常量值。(JLS 13.1)

        2
  •  2
  •   MeBigFatGuy    14 年前

    不幸的是,您的问题不够具体,无法回答问题,因为如果不重新编译,问题可能会更改,也可能不会更改。下面是一个例子,其中常量值 更改为不重新编译。

    public class Const {
       public static final int CONSTANT;
       static {
          CONSTANT = 4;
       }
    }
    
    class Test
    {
       int c = Const.CONSTANT;
    }
    

    这里有一个案例 不会 更改而不重新编译

    public class Const {
       public static final int CONSTANT = 4;
    }
    
    class Test
    {
       int c = Const.CONSTANT;
    }
    
        3
  •  1
  •   Community holdenweb    7 年前

    不,它不会获取新值。这是语言规范的一部分。请参见 this question .

        4
  •  1
  •   chrislatimer    14 年前

    根据JVM规范:

    类变量是在类声明中使用关键字static(_§2.9.1)声明的类类型字段,或在接口声明中使用或不使用关键字static声明的字段。类变量是在加载类或接口时创建的(_§2.17.2),并在创建时初始化为默认值(_§2.5.1)。当卸载类或接口时,类变量有效地停止存在(_§2.17.8)。

    因此,当类加载器加载OutsideLibraryClass时,该值将被初始化。在MyVal上执行赋值语句时,该值将在运行时基于类加载器加载的OutsideLibraryClass类文件加载。因此,如果关闭JVM,交换包含OutsideLibraryClass的JAR文件并再次运行它,它将从新类中获得值。

    更新

    如果你说的是 实例 方法中的局部变量。如果您的myval变量是在类级别声明的,那么表示它不会更改的人是正确的。