1

I got this piece of code from a commercial product. I believe that it will always throw the java.lang.NullPointerException exception when this.result is null. Am I right to say that?

private void closeCurrentResult() throws SQLException {
    this.lastUpdateCount = -1;
    if(this.result != null) {
        this.result.close();
    }

    this.result = null;
}

if this.result is null, then

this.result = null

is equivalent to

null = null;

while causes the NPE.

After read through some of the replies, I think the thing becomes clear. I also did a test as the code shown below:

public class NullTest {
    public static void main(String[] args) {
        ABC a = new ABC(null);
        a.test();
    }

    static class ABC {
        Object result;

        ABC(Object result) {
            this.result = result;
        }

        void test() {
            if (this.result != null) {
                System.out.println("do something");
            }

            this.result = null;
        }
    }
}

And it works just fine.

5
  • Where do you think the NPE will be thrown? Commented May 3, 2015 at 14:16
  • this line: this.result = null; Commented May 3, 2015 at 14:17
  • 3
    Since result is not being dereferenced (you're not calling a method on result), no NPE will be thorwn. Also, assigning it a new value (whatever it is) will not cause the NPE even if the original reference was null. Commented May 3, 2015 at 14:18
  • I really recommend you to read an introductory book on Java :) Commented May 3, 2015 at 14:26
  • @kuporific Can references really be null? I assume that the values held by a reference can be null but not a reference itself. Commented May 3, 2015 at 14:28

5 Answers 5

2

Let's go through it step by step:

first this.lastUpdateCount = -1; does nothing but setting a global member variable to -1.

if(this.result != null)

This one (guard clause) tests, whether result is null if not so this.result.close(); the close() method on result is called. The guard says, it's safe to do so. After that this.result = null; sets result to null anyways.

After this codeblock, two things are assured:

1) this.result is null

2) And if this.result had something open it is now close

if this.result is null, then this.result = null is equivalent to null = null;

this.result = is an assignment statement: You are assigning something to this.result, whose value may be null. This operation is NPE-safe.

Sign up to request clarification or add additional context in comments.

Comments

2

No.. this.result = null simply assigns null reference to this.result.

It will throw NPE only when this == null, which is...never.

NPE means you invoked a method or referred a property on a null reference. That is to say, when your code is like this:

obj.someProperty or obj.someMethod() when obj itself is null.

BTW, null reference is a special reference (instead of a special value or some compile-time mechanism).

  1. All the null reference is identical (same reference).

    String a = null;
    Person p = null;
    assert a == b;
    
  2. null reference is the "default value" for reference-type variables.

    class Person{
        String name;  // `name` is null until assigned otherwise.
    }
    
  3. NPE will be thrown when unboxing a null reference variable.

    Integer a = null;
    int b = a;  // throws NPE.
    
  4. Many JDK methods threat null reference specially.(Which is good and bad.)

    String a  = null;
    System.out.println(a);  
    // will NOT throw NPE because:
    // PrintStream.java:
    public void println(String var1) {
        synchronized(this) {
            this.print(var1);
            this.newLine();
        }
    }
    

Another example:

    String b = null;
    String a = String.valueOf(b);
    // a is String "null" instead of null reference. Because:
    // String.java:
    public static String valueOf(Object var0) {
        return var0 == null?"null":var0.toString();
    }

1 Comment

Yes, understand better now. Thanks for your explanation.
1

No, you are not.

This:

if(this.result != null) {
    this.result.close();
}

Call close() only if this.result is not null, correct. This would have thrown a NullPointerException if the check would have been this.result != null.

The last line:

this.result = null;

Simply set this.result as null, nothing wrong here either.

3 Comments

if this.result is null, it is like to assign null to null, this does't work right?
result is a reference to a null. The reference itself is not null.
No, that DOES work, when you assign null to a variable you are just changing its value, as @ChetanKinger points out.
0

The result is like a label to a memory address. When result is not null, it's pointing to some memory address where there is an object.

When you use the assignment operator =, as in result = null, you're saying, "make result point to null and I don't care what it was originally pointing at". So whatever result is currently pointing to does not matter, even if it's null, reassigning result to null will not throw a NPE.

Comments

0

The code you posted won't throw a null pointer exception. But after setting the result as null you try to access any method it will throw a null pointer exception.

private void closeCurrentResult() throws SQLException {
    this.lastUpdateCount = -1;
    if(this.result != null) {
        this.result.close();
    }
    this.result = null;
    this.result.someMethod(); //Will throw a Null Pointer Exception
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.