50

I wrote this program in Java

public class Why {

  public static void test() {
    System.out.println("Passed");
  }

  public static void main(String[] args) {
    Why NULL = null;
    NULL.test();
  }

}

I read that invoking a method on a null object causes NullPointerException, and yet the above program doesn't? Why is this? Am I not understanding something correctly?

polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
Artjem
  • 511
  • 1
  • 4
  • 4
  • 1
    A static member variable is created as soon as the class is loaded by the Java interpreter, and the initialization is also done at that time. –  Jul 20 '10 at 19:08
  • 6
    Since you're learning, you should familiarize yourself with the coding convention: http://java.sun.com/docs/codeconv/html/CodeConventions.doc8.html : specifically, all-uppercase names are reserved for constants. – polygenelubricants Jul 20 '10 at 19:14
  • 1
    ...although I suppose that may be your intention in the first place since you probably wanted `NULL` to always be `null`, in which case you'll probably want to learn about `final` keyword and what it means for fields vs local variables (and classes and methods). – polygenelubricants Jul 20 '10 at 19:26
  • Here you can find compiler level implementation of static. http://stackoverflow.com/q/21037406/1686291 – Not a bug Jan 15 '14 at 07:23
  • It might be interesting to know that, when accessing the method through `Why[] w = new Why[2]; w[3].test();` there will be an ArrayIndexOutOfBoundsException – Dani Aug 22 '15 at 18:25
  • 1
    i loved it `Why NULL = null;` – Abdul Mohsin Dec 12 '17 at 07:13

5 Answers5

81

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

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
4

Static methods do not need a reference to the object. So you can call it even reference to the object is null. That's how main method works.

Try removing static designation from the object to see the null pointer exception.

Vlad
  • 9,180
  • 5
  • 48
  • 67
3

It's a static method, which allows you to call methods on it without instantiating an instance.

JohnFx
  • 34,542
  • 18
  • 104
  • 162
3

You should turn on the various warnings in your IDE. Chances are you will see a warning about accessing a static member in a non-static way.

You could do something like (Why)(null).test(), it is only using the (Why)(null) to get the class.

MrJacqes
  • 373
  • 1
  • 4
1

Static Variable & Methods are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory.

Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class and the same apply for Static Method. for more refer this.

Rupesh Yadav
  • 12,096
  • 4
  • 53
  • 70