How Come Invoking a (Static) Method on a Null Reference Doesn't Throw Nullpointerexception

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.nameIn 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



Leave a reply



Submit