Xiaogegexiao
Xiaogegexiao

Reputation: 111

Java NullPointerException in argument

String a = null;
String b = null;
try {
    a.equals(b.toString());
} catch (Exception e) {
    e.printStackTrace();
}

I know that a NPE will be thrown, but what I want to know is will it be thrown by b.toString() before a.equals() is called?

Upvotes: 1

Views: 96

Answers (4)

Obicere
Obicere

Reputation: 3019

As the others have pointed out, the error will come from b.toString().

You can see this, by changing things around a little bit:

public class Foo {

    public static void main(final String[] args) {

        Foo a = null;
        Foo b = new Foo(); // Won't throw a NPE now.

        try {
            a.equals(b.foo());
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    public Foo foo() {
        throw new AssertionError("Some other error");
    }

}

Which will throw the error:

Exception in thread "main" java.lang.AssertionError: Some other error
    at Foo.foo(Foo.java:19)
    at Foo.main(Foo.java:12)

Verifying that the error will come from the parameters.


Viewing the Bytecode will also show the order of execution. The bytecode for the try block:

     TryCatch: L6 to L7 handled by L8: java/lang/Exception
     L3 {
         aconst_null
         astore1
     }
     L5 {
         new float
         dup
         invokespecial Foo <init>(()V);
         astore2
     }
     L6 {
         aload1
         aload2
         invokevirtual Foo foo(()LFoo;);
         invokevirtual java/lang/Object equals((Ljava/lang/Object;)Z);
         pop
     }
     L7 {
         goto L2
     }
     L8 {
         astore3
     }
     L1 {
         aload3
         invokevirtual java/lang/Exception printStackTrace(()V);
     }
     L2 {
         return
     }
     L4 {
     }

In L6, the Foo#foo() method is called on the line before Object#equals(Object) is called. So the error will be thrown from b in both cases.

Upvotes: 1

Razib
Razib

Reputation: 11173

Yes the exception will be thrown from B.toString(). Since A.equals() method will come to the scene after B.toString() evaluated.

Upvotes: 0

Ankur Shanbhag
Ankur Shanbhag

Reputation: 7804

It will be thrown for B.toString(). Stack of expression is created and stack is a LIFO data structure. B.toString() goes in last and come out first.

Upvotes: 0

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280167

Yes, arguments in method invocation expressions are evaluated before the method invocation itself. So the exception will be raised for B.toString().

Upvotes: 1

Related Questions