class Program { static final int var; static { Program.var = 8; // Compilation error } public static void main(String[] args) { int i; i = Program.var; System.out.println(Program.var); } }
class Program { static final int var; static { var = 8; //OK } public static void main(String[] args) { System.out.println(Program.var); } }
Why does Case 1 cause a compilation error?
Yes of course: static final variables can be initialized in a static block but.... you have implicit GOTOs in that example ( try/catch is essentially a 'GOTO catch if something bad happens'). If an exception is thrown your final variables will not be initialized.
You can declare a variable static inside a static block because static variables and methods are class instead of instance variable and methods. This means that you wont be able to see a static field inside a method because it will be inside an inner scope and won't be a class variable at all...
Static variables are normally declared as constants using the final keyword. Constants are variables that are declared as public/private, final, and static. Constant variables never change from their initial value.
The static keyword means the value is the same for every instance of the class. The final keyword means once the variable is assigned a value it can never be changed. The combination of static final in Java is how to create a constant value.
The JLS holds the answer (note the bold statement):
Similarly, every blank final variable must be assigned at most once; it must be definitely unassigned when an assignment to it occurs. Such an assignment is defined to occur if and only if either the simple name of the variable (or, for a field, its simple name qualified by this) occurs on the left hand side of an assignment operator. [§16]
This means that the 'simple name' must be used when assigning static final variables - i.e. the var name without any qualifiers.
Apparently this is a cheap syntactic trick to limit definite (un)assignment analysis within the class itself.
If the field is syntactically qualified with a class name, the code is usually in another class, where the analysis cannot reach.
This trick fails in your example. Other examples of oddity:
static class A { static final int a; static { // System.out.println(a); // illegal System.out.println(A.a); // compiles! a = 1; } }
If they had more resources, they probably would've made a finer rule. But we can't change spec now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With