Take a look at below code:
class Foo{ public static int x = 1; } class Bar{ public static void main(String[] args) { Foo foo; System.out.println(foo.x); // Error: Variable 'foo' might not have been initialized } }
As you see while trying to access static field x
via an uninitialized local variable Foo foo;
code foo.x
generates compilation error: Variable 'foo' might not have been initialized
.
It could seem like this error makes sense, but only until we realize that to access a static
member the JVM doesn't actually use the value of a variable, but only its type.
For instance I can initialize foo
with value null
and this will let us access x
without any problems:
Foo foo = null; System.out.println(foo.x); //compiles and at runtime prints 1!!!
Such scenario works because compiler realizes that x
is static and treats foo.x
as if it was written like Foo.x
(at least that is what I thought until now).
So why compiler suddenly insists on foo
having a value which it will NOT use at all?
Disclaimer: This is not code which would be used in real application, but interesting phenomenon which I couldn't find answer to on Stack Overflow, so I decided to ask about it.
In Java, a static variable is a class variable (for whole class). So if we have static local variable (a variable with scope limited to function), it violates the purpose of static. Hence compiler does not allow static local variable.
There will be no default values or ability to run the code. It will be a compile time error and your code won't run. If the variables were class fields they would get default values for certain types or null otherwise.
But static contexts(methods and blocks) doesn't have any instance they belong to the class. In a simple sense, to use “this” the method should be invoked by an object, which is not always necessary with static methods. Therefore, you cannot use this keyword from a static method.
A non-static method belongs to an object of the class and you have to create an instance of the class to access it. Non-static methods can access any static method and any static variable without creating an instance of the class.
§15.11. Field Access Expressions:
If the field is static:
The Primary expression is evaluated, and the result is discarded. If evaluation of the Primary expression completes abruptly, the field access expression completes abruptly for the same reason.
Where earlier it states that field access is identified by Primary.Identifier
.
This shows that even though it seems to not use the Primary
, it is still evaluated and the result is then discarded which is why it will need to be initialized. This can make a difference when the evaluation halts the access as stated in the quote.
EDIT:
Here is a short example just to demonstrate visually that the Primary
is evaluated even though the result is discarded:
class Foo { public static int x = 1; public static Foo dummyFoo() throws InterruptedException { Thread.sleep(5000); return null; } public static void main(String[] args) throws InterruptedException { System.out.println(dummyFoo().x); System.out.println(Foo.x); } }
Here you can see that dummyFoo()
is still evaluated because the print
is delayed by the 5 second Thread.sleep()
even though it always returns a null
value which is discarded.
If the expression was not evaluated the print
would appear instantly, which can be seen when the class Foo
is used directly to access x
with Foo.x
.
Note: Method invocation is also considered a Primary
shown in §15.8 Primary Expressions.
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