public class Main {
static final int alex=getc();
static final int alex1=Integer.parseInt("10");
static final int alex2=getc();
public static int getc(){
return alex1;
}
public static void main(String[] args) {
final Main m = new Main();
System.out.println(alex+" "+alex1 +" "+alex2);
}
}
Can someone tell me why this prints: 0 10 10? I understand that it’s a static final variable and its value shouldn’t change but it`s a little difficult to understand how the compiler initializes the fields.
This situation is covered by JLS 8.3.2.3 “Restrictions on the use of Fields during Initialization”.
The JLS rules allows the usage in your Question, and state that the first call to
getc()will return default (uninitialized) value ofalex.However, the rules disallow some uses of uninitialized variables; e.g.
is disallowed.
Re some of the other answers. This is not a case where the Java compiler “can’t figure it out”. The compiler is strictly implementing what the Java Language Specification specifies. (Or to put it another way, a compiler could be written to detect the circularity in your example and call it a compilation error. However, if it did this, it would be rejecting valid Java programs, and therefore wouldn’t be a conformant Java compiler.)
In a comment you state this:
This is not correct.
There are actually two kinds of
finalfields:A so-called “constant variable” is indeed evaluated at compile time. (A constant variable is a variable “of primitive type or type String, that is final and initialized with a compile-time constant expression” – see JLS 4.12.4.). Such a field will always have been initialized by the time you access it … modulo certain complications that are not relevant here.
Other
finalfields are initialized in the order specified by the JLS, and it is possible to see the field’s value before it has been initialized. The restriction onfinalvariables is that they must be initialized once and only once during class initialization (for astatic) or during object initialization.Finally, this stuff is very much “corner case” behavior. A typical well-written class won’t need to
access a
finalfield before it has been initialized.