Reputation: 1022
public class JavaPuzzler {
public static void main(String[] args) {
JavaPuzzler javaPuzzler = null;
System.out.println(javaPuzzler.get());
}
private static String get(){
return "i am a java puzzler";
}
}
You might think that it should throw NullPointerException because the main method invokes get() method on local variable which is initialized to null, and you can’t invoke a method on null.
But if you run this program, you will see that it prints “i am a java puzzler”.
Upvotes: 11
Views: 3644
Reputation: 359
In the above code you have given get() function as static. Static functions and data members do no belong to any object. They belong to the class. You can call static function using object of class but thats not a good approach as it consumes extra memory.
Since static, JavaPuzzler.get()); will give you the output and not null pointer exception.
It would have given null pointer exception in case the get() method would have been non static.
Upvotes: 0
Reputation: 7311
The compiler changes the instance call to a class call automatically. If you have a decompiler you can observe the change in the generated byte code:
...
public static main([Ljava/lang/String;)V
L0
LINENUMBER 8 L0
ACONST_NULL
ASTORE 1
L1
LINENUMBER 9 L1
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
INVOKESTATIC JavaPuzzler.get()Ljava/lang/String;
INVOKEVIRTUAL java/io/PrintStream.println(Ljava/lang/String;)V
L2
LINENUMBER 11 L2
RETURN
L3
LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
LOCALVARIABLE javaPuzzler LJavaPuzzler; L1 L3 1
MAXSTACK = 2
MAXLOCALS = 2
...
Upvotes: 0
Reputation: 17516
Like everyone mentions here, it works because get()
is a static method. Here's a way that you can think about this:
When you define a class in Java, what you're essentially doing is defining the data that an object will hold, and a set of methods that operate on that data. Now while you can have thousands and thousands of objects, it doesn't make sense to have copies of all the methods for each of them. What happens is that the class stores the methods you define, and executes them in the scope of the object that you call the method on. If you attempt to call these methods on an uninitialized object, the object still exists and the method still exists, but it has no valid to scope to work on, thus giving you the NullPointerException
.
The exception to this rule is static methods, which are methods that don't need a scope - they don't refer to object-specific data. This is why they can run irrespective of whether the object is initialized or not.
Just remember that objects don't have copies of their methods... the methods are just called in the scope of the object's data. So you can still access the methods of null (uninitialized) objects, but non-static methods have no data to work on.
Upvotes: 1
Reputation: 20061
It's because the method is static and though you reference an instance, the instance isn't necessary. The Java Language Specification explains why in section 8.4.3.2:
A method that is declared static is called a class method. A class method is always invoked without reference to a particular object.
This means that it does not matter if javaPuzzler
instance is null - the method "belongs" to the class, not an instance.
Upvotes: 4
Reputation: 20940
If we try calling a method using NULL object it will throw NullPointerException
as long as the method is not static.
If method is static it will run.
Read HERE for more reference
Upvotes: 1
Reputation: 37566
You are calling a static methode, you dont need an instance to call it, thats why it works.
Upvotes: 1
Reputation: 3902
The get
method is static, which means that the actual reference in javaPuzzler
is ignored in that call, only the variable's type is used.
Upvotes: 3
Reputation: 17375
Your method is static. So it could only be called in a static way.
So even though you are putting it as javaPuzzler.get(), actual call will be JavaPuzzler.get() and thus the printing!!
Upvotes: 1
Reputation: 126864
In your code sample, get()
is a static member that belongs to the class, not to an instance. You do not need an instance in order to invoke the method.
public static String get() // belongs globally to class, no instance required
public String get() // belongs to instance
Upvotes: 8