views:

480

answers:

7

I thought Java had short circuit evaluation, yet this line is still throwing a null pointer exception:

if( (perfectAgent != null) && (perfectAgent.getAddress().equals(entry.getKey())) ) {

In this case perfectAgent is null, so I just want the whole expression to return false, but my app is still crashing on this line with a NullPointerException.

EDIT, general response:

Since perfectAgent is null, nothing to the right of the && should be executed, as it is impossible for the expression to be true. More to the point, it is impossible to execute perfectAgent.getAddress() since perfectAgent does not contain a valid reference (it being null and all). I'm trying to use short circuit evaluation to not have to check for null in a seperate statement as that makes the logic more sloppy.

EDIT 2 (or, I'm an idiot): Yeah, like many things in life you figure out the answer right after announcing to the world that you're a moron. In this case, I had turned off Eclipse's autobuild while doing something else and not turned it back on, so I was debugging class files that didn't match up with my source.

+2  A: 

You ensure that perfectAgent is not null, so one or more of perfectAgent.getAddress() or entry or entry.getKey() must be null. Or getAddress() or getKey() are hitting an NPE in their implementation.

To debug this sort of thing, look first at the stack trace to pin down the location. This would tell you if it's happening in getAddress() or in getKey() or in the pasted code snippet that calls them. Next, if it's in this snippet, add some code before the if to test which is null. You can use good old System.err.println() or assertions. (If you use assertions, be sure to enable them with the java command's -enableassertions flag.)

Update: So my interpretation turned out to be wrong ... the problem presented two contradictory facts (there was an NPE on this line and yet the short-circuit should have happened) and I automatically assumed the first fact was true and the second false when in fact it was a different problem entirely due to turning off the auto-build in Eclipse. Duh! In debugging something "impossible" it helps to be radically skeptical.

Jim Ferrans
+4  A: 

Java does have short circuit evaluation. Perhaps entry is null and so entry.getKey() is causing the NullPointerException. Another possibility is that getAddress() either returns null or has a NullPointerException happening inside somewhere (if it's more complicated than a simple return statement).

EDIT: I see your edit where you claim this:

More to the point, it is impossible to execute perfectAgent.getAddress() ...

But what if perfectAgent.getAddress() is successfully executed and returns null? See what I mean...

Asaph
A: 

There are three references other than perfectAgent that could be null:

  • perfectAgent.getAddress()
  • entry
  • entry.getKey()

Break up the statement or run it in a debugger.

Jim Garrison
`entry.getKey()` being null wouldn't result in a `NullPointerException` in the OP's code snippet.
Asaph
Object.equals(null) returns false always. So it wouldn't be entry.getKey() returning null. So it must be one of the first two listed.
Sean A.O. Harney
Ah yes, you're both correct. Only the first two are candidates.
Jim Garrison
+3  A: 

If perfectAgent is genuinely null, that code won't throw an exception (at least assuming there aren't weird threading things going on, changing it from non-null to null half way through the expression). I would be utterly shocked if you could produce a short but complete program demonstrating it doing so.

So yes, your intuition is right - this shouldn't be a problem. Look elsewhere for the cause. I strongly suspect that perfectAgent isn't actually null, and that you're running into any of the other situations in that code which could cause an exception.

I suggest you try to extract that bit of code out into a short but complete example - if you can do so, I'll eat my metaphorical hat; if not, you'll hopefully find the problem while you attempt the extraction.

What makes you think that perfectAgent really is null? Try inserting this code before it:

if (perfectAgent == null)
{
    System.out.println("Yup, it's null");
}

Another very, very slim possibility is that you've run into a JIT bug - but I highly doubt it.

Jon Skeet
Oh, yeah, I didn't think it was a JIT bug, was just trying to figure out what I did wrong.
Donnie
You didn't do anything wrong in the code you've shown - at least nothing that would cause this. I suspect it's something in whatever's leading you to believe that perfectAgent is null :)
Jon Skeet
See my Edit2. Right on the nose.
Donnie
@Downvoter: Care to comment?
Jon Skeet
Even if perfectAgent is genuinely null, that code *can* still throw an NPE later on.
Jim Ferrans
@Jim: If `perfectAgent` is genuinely null, nothing beyond the null comparison (out of the code shown) will be executed due to short-circuiting. Yes, the next line of code may throw an NPE - but the code shown won't.
Jon Skeet
Jon, I'm an idiot, sorry! My kids were heading back to school when I read/wrote this. I'll reverse.
Jim Ferrans
A: 

Big mistery. I copied your line of code and tested with perfectAgent == null, entry == null, entry.getKey() == null and combinations of those: No NPE in my test bed (Java 1.6).

Whatever annoying bug it is, I doubt that it has something to do with short circuit evaluation. If it's this line causing NPE, than, as far as I can say, perfectAgent is not null. Good luck and - show us the bug once you've catched it :)

Andreas_D
A: 

Try formatting your code like this:

if( 
  (perfectAgent != null) 
  && (
      perfectAgent.getAddress()
      .equals(
       entry.getKey()
      )
     ) 
  ) {

It should give you a better stack trace line entry.

Nathan Feger
+1  A: 

Advanced debugging lesson #1:

If you run into a seemingly impossible error (e.g. one that contradicts you knowledge about Java), do the following:

  • Consult a reputable text book (or better still, the relevant standard) to confirm that your understanding is not flawed. (In this case your understanding was correct, and any half-decent textbook would confirm this in a minute.)

  • Check all of the stupid things that you could have done that could cause the impossible error. Things like not saving a file, not doing a complete build, running an old / stale version of the application, being in the wrong directory, and so on.

In summary, learn to doubt yourself a bit more.

Stephen C