问题描述
假设我有一个Java应用程序,它使用来自库的(静态)int常量:
int myval = OutsideLibraryClass.CONSTANT_INT;
现在,在不重新编译我的应用程序的情况下,我针对稍微不同的OutsideLibraryClass版本运行它,其中CONSTANT_INT的值不同。
我的应用程序是否会看到新值(因为它在运行时选择它)或旧的(因为值在我的方法中编译成字节码)? 如果CONSTANT_INT是最终的,它会有什么不同吗? Java规范中是否有一部分涉及此问题?
1楼
对常量字段的引用在编译时解析为它们表示的常量值。 (JLS 13.1)
2楼
不幸的是,你的问题不够具体,无法回答这个问题,因为如果不重新编译,它可能会也可能不会改变。 这是一个示例,其中常量值将随着重新编译而改变。
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楼
不,它不会拿起新的价值。 这是语言规范的一部分。 看到 。
4楼
从JVM规范:
类变量是在类声明中使用关键字static(第2.9.1节)声明的类类型的字段,或者在接口声明中使用或不使用关键字static。 加载类或接口时会创建类变量(第2.17.2节),并在创建时将其初始化为默认值(第2.5.1节)。 当类或接口被卸载时,类变量实际上不再存在(第2.17.8节)。
因此,当ClassLoader加载OutsideLibraryClass时,该值将被初始化。 在myVal上执行赋值语句时,将根据ClassLoader加载的OutsideLibraryClass类文件在运行时加载该值。 因此,如果关闭JVM,交换包含OutsideLibraryClass的jar文件并再次运行它,它将从新类中获取值。
UPDATE
如果您在方法中讨论
实例
是局部变量,则上述陈述是正确的。
如果你的myVal变量在类级别声明,那么说它不会改变的人是正确的。