How come invoking a (static) method on a null reference doesn't throw NullPointerException?
test()
is a static
method. A static
member belongs to the type, and do not require an instance to access.
A static
member should ONLY be accessed via a type expression. That is, you should've written it as follows:
Why.test(); // always invoke static method on the type it belongs to!
Java does allow you to access a static
member via an object reference expression, but
this is VERY misleading, since this is NOT the actual semantics of a static
member access.
Why aNull = null;
aNull.test(); // DO NOT EVER DO THIS!
// invokes Why.test(), does NOT throw NullPointerException
When accessing a static
member through an object reference expression, only the declared type of the reference matters. This means that:
- It doesn't matter if the reference is actually
null
, since no instance is required - If the reference is not
null
, it doesn't matter what the runtime type of the object is, there is no dynamic dispatch!!!
As you can see, the exact opposites are true on both points for instance member access. This is why static
members should NEVER be accessed in a "non-static
" way, because it gives a very misleading appearance on what it's actually doing.
Related questions
- Why doesn't Java allow overriding of static methods ? (understanding
this
is crucial!) - Why isn’t calling a static method by way of an instance an error for the Java compiler?
Why does a call on a static method returning null not result in a NullPointerException?
Your code is working as static String name = "New york";
is static.
Remove the static
from it it will throw a NullPointerException
. Static members do not need an object to call as a static member are class level members. Below code will also work.
JavaApplication1 application = null;
System.out.println(application.name);
Your getCity().name
is same as JavaApplication1.name
In your case compiler will give you a warning like below
The static field JavaApplication1.name should be accessed in a non-static
way
Why not a NullPointerException while accessing static with null reference?
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:
class Test3 {
static String mountain = "Chocorua";
static Test3 favorite(){
System.out.print("Mount ");
return null;
}
public static void main(String[] args) {
System.out.println(favorite().mountain);
}
}
It compiles, executes, and prints:
Mount Chocorua
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.
Why does this method call on a null object run without a NullPointerException?
This is because greet()
is a static method. So
((Null)null).greet();
is equivalent to,
Null.greet()
Accessing static method using null object
Static methods are not linked with objects. Those are class methods. When you call rt.dir(1)
, JVM replaces it with Root.dir(1)
.
It's the instance that can be null and can cause NPE, but not the classes. This is why you cannot see any NullPointerException
here.
NullPointerException when invoking a static method for data input
You never initialise the contents of the productRange
array
Product [] productRange = new Product[range];
Creates an array capable of Product
whose elements are all null
You then try to "modify" each element...
for(int i = 0; i < range; i++)
{
productRange[i].setProductCode(codeDataScan.next());
productRange[i].setPricePerUnit(Integer.
parseInt(priceDataScan.nextLine()));
}
Which is the probable cause of you NPE
You need to intiailsie the element of the array BEFORE you initialise it
for(int i = 0; i < range; i++)
{
productRange[i] = new Product();
productRange[i].setProductCode(codeDataScan.next());
productRange[i].setPricePerUnit(Integer.
parseInt(priceDataScan.nextLine()));
}
When diagnosing these types of problems, you can use System.out.println
(or an appropriate logger) to help you identify problem areas and use the debugger to inspect the state (and flow) of your program.
What happens when a static method is invoked using a null object reference?
It's been optimized away by the compiler, simply because having an instance of the class is not necessary. The compiler basically replaces
csm.method();
by
CallingStaticMethod.method();
It's in general also a good practice to do so yourself. Even the average IDE would warn you about accessing static methods through an instance, at least Eclipse does here.
Why does Java compiler allow static variable access through null object?
To add some additional info to the current answers, if you disassemble your class file using:
javap -c TestClass1
You'll get:
Compiled from "TestClass1.java"
public class TestClass1 extends java.lang.Object{
static int a;
public TestClass1();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
5: aload_1
6: pop
7: getstatic #3; //Field a:I
10: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
13: return
static {};
Code:
0: bipush 10
2: putstatic #3; //Field a:I
5: return
}
Here you can see that the access to the static field is done in line 7 by the getstatc
instruction. Whenever a static field is accessed through code, a corresponding getstatic
instruction will be generated in the .class
program file.
*static
instructions have the particularity that they don't requiere a reference to the object instance to be in the stack prior to calling them (like, for example invokevirtual which does require an object ref in the stack), they resolve the field/method using just an index to the run time constant pool that will be later used to solve the field reference location.
That's a technical reason for the warning "The static field should be accessed in a static way" that some IDEs will throw at you when you write t1.a
, because the object instance is unnecessary to resolve the static field.
Related Topics
Regex to Match Only Commas Not in Parentheses
How to Use an Internet Time Server to Get the Time
Java Cannot Make a Static Reference to Non-Static Field
Concurrentmodificationexception Despite Using Synchronized
How to Put Axis on a .Png File in Java
Where Is Java_Home on MACos Mojave (10.14) to Lion (10.7)
How to Inject a Property Value into a Spring Bean Which Was Configured Using Annotations
Difference Between @Before, @Beforeclass, @Beforeeach and @Beforeall
How to Handle Invalid Ssl Certificates with Apache Httpclient
Calculate Size of Object in Java
How to Make Httpurlconnection Use a Proxy
Build Eclipse Java Project from Command Line
Modify Request Parameter with Servlet Filter
What Is the Best Approach for Using an Enum as a Singleton in Java