This question already has an answer here:
Here in following code we are getting value of i
on a null reference, though a NPE
is not there.
public class Test {
static int i = 10;
Test getTest() {
return null;
}
public static void main(String args[]) {
Test t = new Test();
System.out.println(t.getTest());
System.out.println(t.getTest().i);
}
}
output
null
10
The generated bytecode looks like this:
As you see,
t.getTest()
is indeed called (21,22), but its result not used (25). The fieldi
is accessed in a static way (26). Java Bytecode has no way of accessing static members via an instance. Note that this means thatt.getTest().i
andTest.i
are not equivalent expressions! In a hypothetical syntax, the equivalent could look like this (using the semantics I'd find intuitive for this syntax:Note that the same holds for a field
test
:t.test.i
is different fromTest.i
. Although getting the field can't have any side effects and is not a valid statement on its own, the field access could still be advised by AspectJ or something similar.Static methods or variables does not need a reference to the object. You can call it even reference to the object is null.
To be more specific,
While accessing the
Static
variable, compiler will generate angetStatic
instruction corresponding to thatstatic
and it will be used to access thatstatic
. thus static are instance independent they are resolved by the field/method using just an index to the run time constant pool that will be later used to solve the field reference location..For more details refer this SO answer : https://stackoverflow.com/a/21047440/1686291
Simply speaking, compiler takes statics from class def, not from an object. That is why you can replace
t.getTest().i
withTest.i
and it will be the same.From Java Language Specifications
Receiver Variable Is Irrelevant For static Field Access
The following program demonstrates that a null reference may be used to access a class (static) variable without causing an exception:
It compiles, executes, and prints:
Even though the result of favorite() is null, a NullPointerException is not thrown. That "Mount " is printed demonstrates that the Primary expression is indeed fully evaluated at run time, despite the fact that only its type, not its value, is used to determine which field to access (because the field mountain is static).
Implies even though primary expression (Here is instance) is evaluated at run time, but its value is discarded and only its type is considered.
Informally speaking, you can think of this
as being equivalent to
because
i
is static.This is the simplest answer probably.
Strictly speaking, they are not equivalent. Actually
getTest()
is called but its return value is not usedfor accessing the
i
field as this test below shows.