Static fields on a null reference in Java
Asked Answered
I

5

119

static members (static fields or static methods) in Java are associated with their respective class rather than the objects of this class. The following code attempts to access a static field on a null reference.

public class Main
{
    private static final int value = 10;

    public Main getNull()
    {
        return null;
    }

    public static void main(String[] args)
    {
        Main main=new Main();
        System.out.println("value = "+main.getNull().value);
    }
}

Although main.getNull() returns null, it works and displays value = 10. How does this code work?

Individualize answered 20/7, 2012 at 13:3 Comment(3)
Maybe this question can help you understand it: How come invoking a (static) method on a null reference doesn't throw NullPointerException?Postmark
For fun, try Main main = null; main.getNull().value.Meatus
This reminds me of new Thread[]{}[-1].sleep(10); where sleep() is a static method. This used to succeed on some older Java versions.Strawworm
C
93

That behaviour is specified in the Java Language Specification:

a null reference may be used to access a class (static) variable without causing an exception.

In more details, a static field evaluation, such as Primary.staticField works as follows (emphasis mine) - in your case, Primary = main.getNull():

  • The Primary expression is evaluated, and the result is discarded. [...]
  • If the field is a non-blank final field, then the result is the value of the specified class variable in the class or interface that is the type of the Primary expression. [...]
Chatter answered 20/7, 2012 at 13:6 Comment(5)
If anyone has info about why this choice was made, that would be interesting.Gearing
@JonofAllTrades I think this is obvious: it is reasonable to not throw any exceptions when calling on a null reference because it doesn't matter since the method is static.Lesbos
@JonofAllTrades : the real question is why the choice of allowing static members to be called as instance was made... To me, it appears to only lead to confusion and less readable code.Vivisection
@Falanwe: Agreed, and it's a construct for which I've not had a need, though I mostly work in .NET where it's not allowed. I guess you might want to call the appropriate static method of a subclass when you're given a reference to a parent class.Gearing
@Vivisection This is allowed, but raises a warning in Eclipse: "The static field Main.value should be accessed in a static way". At least those of us picky about warnings (like me) would avoid such code.Infrasonic
H
19

Because, as you said, static fields are not associated with an instance.

The ability to access static fields from an instance reference (as you are doing) is merely a syntactic sugar and has no additional meaning.
Your code compiles to

main.getNull(); 
Main.value
Hengist answered 20/7, 2012 at 13:5 Comment(1)
I would call it syntactic sugar, more like syntactic saw-dust ;)Saberio
I
3
  1. Accessing a static member with the class name is legal, but its no were written that one cannot access the static member using the object reference variable. So it works over here.

  2. A null object reference variable is allowed to access a static class variable without throwing an exception either at compile or run time.

Iraidairan answered 20/7, 2012 at 13:10 Comment(0)
C
3

When ever you access a static variable or method with objects at compile time it converted to Class name. eg:

Main main = null;
System.out.println(main.value);

It will print the value of static variable value because at compile time It will be converted to

System.out.println(Main.value);

Proof:

download decompiler and Decompile your .class file to .java file and you can see all static methods or variable referred object name is automatically replaced by class name.

Claman answered 20/12, 2012 at 9:52 Comment(0)
M
2

Static variable and method always belong to class. So when ever we create any object only non static variable and methods goes to heap along with object but static resides in method area with class. That's why when ever we try to access a static variable or method it converted to class name dot variable or method name.

Please refer below link for more detail.

http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

Magnetize answered 26/12, 2012 at 14:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.