Java short circuit evaluation
Asked Answered
P

7

18

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.

Paresh answered 29/11, 2009 at 21:4 Comment(15)
Have you checked that entry isn't null?Weasand
If perfectAgent is null then indeed the rest of that line shouldn't be executed. Don't see any problem with it as it is now :/Revile
Is it possible for perfectAgent.getAddress() to return null?Disability
Are you sure that getAddress() is not returning null?Intemperate
Shouldn't matter - it shouldn't get as far as evaluating entry or getAddress() if perfectAgent is null. That suggests to me that either perfectAgent isn't really null (how are you checking this?) or you've missed a bracket somewhere when pasting into SO. Can you reduce the code to a class containing a minimal test case (5-10 lines or so) that illustrates the problem and we can check for ourselves?Counterclaim
You're not debugging code in an old jar against newer sources (with different line numbers) are you? I've been bitten by that recently...Counterclaim
Checking inside the eclipse debugger. This is right smack in the middle of a really big complicated series of projects, so I'll see if I can figure out what's special here.Paresh
@SimonJ- Not exactly. But, basically. Old class files, new source. Woot. Thanks.Paresh
@SimonJ- Oh, if you want to make that an answer I'll accept it, since your comment is what made be double check those settings.Paresh
+1 for publicly saying what was the problem, even if it was a bit embarassing.Foyer
Sometimes it takes forever to solve such simple bugs, because you don't expect to have made a mistake like that. I once spend ours debugging a misplaced semicolon....Wheelwright
@MarioOrtegón - only once ? You're lucky... :-)Earthquake
I just struggled figuring out why this gives a NullPointerException if prevAccountName is null: if ((prevAccountName == null) | !prevAccountName.equals(accountName))) { ... } Almost posted it as a question.Bigg
I like the 7 year later downvote. Prime time, guys.Paresh
There's a 2+ years later upvote for you ;) - good question.Dovekie
C
6

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.

Colonial answered 29/11, 2009 at 23:24 Comment(0)
O
10

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.

Orderly answered 29/11, 2009 at 21:21 Comment(6)
Oh, yeah, I didn't think it was a JIT bug, was just trying to figure out what I did wrong.Paresh
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 :)Orderly
See my Edit2. Right on the nose.Paresh
Even if perfectAgent is genuinely null, that code can still throw an NPE later on.Severn
@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.Orderly
Jon, I'm an idiot, sorry! My kids were heading back to school when I read/wrote this. I'll reverse.Severn
D
7

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...

Dominickdominie answered 29/11, 2009 at 21:15 Comment(0)
C
6

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.

Colonial answered 29/11, 2009 at 23:24 Comment(0)
S
2

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.

Severn answered 29/11, 2009 at 21:15 Comment(0)
P
1

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.

Palaeogene answered 29/11, 2009 at 21:17 Comment(3)
entry.getKey() being null wouldn't result in a NullPointerException in the OP's code snippet.Dominickdominie
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.Ube
Ah yes, you're both correct. Only the first two are candidates.Palaeogene
V
1

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 :)

Venturous answered 29/11, 2009 at 21:45 Comment(0)
B
0

Try formatting your code like this:

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

It should give you a better stack trace line entry.

Berget answered 29/11, 2009 at 21:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.