JLS 4.12.4 defines a "constant variable" as follows:
A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).
JLS 13.1 describes how these end up in a class file:
3. A reference to a field that is a constant variable (§4.12.4) must be resolved at compile time to the value V denoted by the constant variable's initializer.
If such a field is static, then no reference to the field should be present in the code in a binary file, including the class or interface which declared the field. Such a field must always appear to have been initialized (§12.4.2); the default initial value for the field (if different than V) must never be observed.
The declaration in class A
public final static int CONSTAN_VALUE_IN_A = 0;
meets the definition of a constant variable, so when it's used in class B
,
int fooBValue = A.CONSTAN_VALUE_IN_A;
the value is resolved at compile time. No reference to A.CONSTAN_VALUE_IN_A
appears in class B
, and instead the resolved value of 0
is compiled into class B.
So, no, there's no way to tell where that value in B
came from unless you can find the source code.
If you don't like this behavior, you can avoid it by changing things so that the conditions of JLS 4.12.4 aren't met, such as by making it not final, or by changing the type so that it's neither a primitive nor a String
. However, the easiest way of making it not a constant variable is to move the initialization into a static initializer:
public final static int CONSTAN_VALUE_IN_A;
static {
CONSTAN_VALUE_IN_A = 0;
}
By the way, this is not new in Java 8; this behavior has been this way for a very long time.