Java8常量池常量依赖项
假设我在文件a.java中定义了一个常量int:Java8常量池常量依赖项,java,java-8,jvm,inline,java-bytecode-asm,Java,Java 8,Jvm,Inline,Java Bytecode Asm,假设我在文件a.java中定义了一个常量int: public final static int CONSTAN_VALUE_IN_A = 0; 当我在另一个文件B.java中使用此值时: int fooBValue = A.CONSTAN_VALUE_IN_A; 在我完成我的项目后,在B.class中,我有: fooBValue = 0 我想知道当我只有没有源代码的B.class文件时,值“0”从哪里来(A.java)。 我听说在使用java8编译时,通过读取B.class中的常量池,我
public final static int CONSTAN_VALUE_IN_A = 0;
当我在另一个文件B.java中使用此值时:
int fooBValue = A.CONSTAN_VALUE_IN_A;
在我完成我的项目后,在B.class中,我有:
fooBValue = 0
我想知道当我只有没有源代码的B.class文件时,值“0”从哪里来(A.java)。
我听说在使用java8编译时,通过读取B.class中的常量池,我可以知道B.java在A.java中使用了一些常量值。
但我不确定如何通过读取常量池来获取常量的实际类。几乎肯定不是
许多静态最终值甚至在编译时被与常量关联的实际值替换
static final int X = 0;
static final int Q = 9;
private void test(String[] args) {
int x = X;
int y = Q;
}
可能在汇编的早期阶段转变为:
private void test(String[] args) {
int x = 0;
int y = 9;
}
因此,发现该值实际来源的可能性非常小。定义了一个“常量变量”,如下所示:
常量变量是使用常量表达式(§15.28)初始化的基元类型或字符串类型的最终变量
描述如何在类文件中结束这些操作:
三,。对常量变量(§4.12.4)字段的引用必须在编译时解析为常量变量初始值设定项表示的值V
如果这样的字段是静态的,那么二进制文件中的代码中不应该存在对该字段的引用,包括声明该字段的类或接口。此类字段必须始终显示为已初始化(§12.4.2);绝对不能遵守字段的默认初始值(如果不同于V)
类A
public final static int CONSTAN_VALUE_IN_A = 0;
满足常量变量的定义,因此在类B
中使用时
int fooBValue = A.CONSTAN_VALUE_IN_A;
该值在编译时解析。类B
中未出现对A.CONSTAN\u值的引用,而是将0
的解析值编译到类B中
因此,不,除非您能找到源代码,否则无法判断B
中的值来自何处
如果您不喜欢此行为,可以通过更改内容以避免不满足JLS 4.12.4的条件来避免此行为,例如使其不是最终的,或者更改类型以使其既不是基元也不是字符串。但是,使其不是常量变量的最简单方法是将初始化移到静态初始化器中:
public final static int CONSTAN_VALUE_IN_A;
static {
CONSTAN_VALUE_IN_A = 0;
}
顺便说一下,这在Java8中并不新鲜;这种行为已经有很长一段时间了。我想知道我是否可以得到值“0”来自哪里
你的确切意思是什么?值是一个值,它不能“来自”。对于引用类型变量来说,有一种谈论相同值的感觉,但不是在这个上下文中。@拖拉者“来自”是指这个常量值的定义位置。@Andremoniy是的,有点像引用,我只是想知道当我阅读B.class文件时,如何知道值0“来自”a.class。请原谅我的表达能力不足。@Raymond,你不是自己定义的吗?因为你的问题说明了这一点,比如说我在a.java文件中定义了一个常量int;你的答案归结起来几乎肯定不是。他们在问题中已经提到的其余部分:在我编译了我的项目之后,在B.class中,我有[…]。@Andremoniy-我对“0”的解释是想知道值“0”是从哪里来的(A.java)是否可以告诉我fooBValue
(即0
)的结果值来自A
类。@SotiriosDelimanolis-正是我的观点-源代码在类文件生成之前确实运行良好,在运行时肯定不可用。我的观点是你只是重复他们已经说过的内容,而你做得不令人信服。编辑你的答案,提供证据,而不是猜测,几乎可以肯定,可能性很小,很可能。从iirc的第一个版本开始。在Java1.1中,确实是这样的。所以,对于B.class文件,我无法理解它引用了A.class中定义的某个常量值,对吗?@Raymond Guo:没错。