This week's book giveaway is in the OCAJP forum.
We're giving away four copies of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) and have Khalid A Mughal & Rolf W Rasmussen on-line!
See this thread for details.
Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Shortcut for throwing a NullPointerException

 
Dennis Grimbergen
Ranch Hand
Posts: 159
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
At my work we have about 15-20 Java developers working on some kind of project. This week I noticed someones code which was new for me...



If 'bla' is true then this results in a NullPointerException. Why is that so? Is it because the throw keyword expects a Throwable to be specified, which is null in this case, therefore resulting in a NullPointerException?
 
Sagar Rohankar
Ranch Hand
Posts: 2907
1
Java Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Strange, I never seen such code in my entire programming life. If i have to code something like this, I must had thrown an exception, may be custom one explaining the reason for exception.
e.g
 
Paul Clapham
Sheriff
Posts: 21322
32
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dennis Grimbergen wrote:Is it because the throw keyword expects a Throwable to be specified, which is null in this case, therefore resulting in a NullPointerException?


Yes, I'd say you got that right.

If I were supervising the programmer who wrote that I would (1) congratulate them on finding a cute trick like that (2) tell them to change it to actually throw a NullPointerException. After all it's been clearly demonstrated that it's a confusing trick, and clear code is better than short code.

However I'd also say that a design which requires application code to explicitly throw a NullPointerException is itself questionable. As Sagar says, there are better choices if you have to throw an unchecked exception.
 
Pat Farrell
Rancher
Posts: 4678
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ouch, that code is terrible. Tell the programmer to stop. As a minimum, use a proper RuntimeException that provides information.

I strongly recommend you look at the Google Guava library and specifically at its Preconditions conditions.

I believe that throwing a NPE is very bad.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree it's hideous, but I truly love this thread. How often do you get to see something in Java that you've never seen before? If you're me, anyway, not often. This is truly new and horrible.

I gave it a try. One interesting thing is that the compiler doesn't complain; somehow "null" is interpreted as a RuntimeException, not as a Throwable, so no "throws" clause is required. I have no idea how this could be:



Not surprisingly, the stack trace is indistinguishable from a "natural" one:



Finally, I checked to see if the compiler was special-casing this; it's not:



I am going to invite my favorite language lawyer to come have a look!
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wow - I agree with everyone who said that (a) they have never seen that one before, (b) it's somehow perverse and wrong and should be changed to something more meaningful, and yet (c) it's still cool to see something new and unexpected like this.

I wonder if the author of the code even did this intentionally. Were they maybe confusing throw with return? Did they discover this once accidentally and now they do it for fun? Weird.

The relevant language rules are found at JLS3 14.18:
ThrowStatement:
        throw Expression ;

[...]

A throw statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the throw completes abruptly for that reason. If evaluation of the Expression completes normally, producing a non-null value V, then the throw statement completes abruptly, the reason being a throw with value V. If evaluation of the Expression completes normally, producing a null value, then an instance V' of class NullPointerException is created and thrown instead of null. The throw statement then completes abruptly, the reason being a throw with value V'.

So yes, surprisingly, they really did this intentionally. Why?

My guess is that they wanted to allow coders some flexibility in how they generate an exception. One might have a helper method that provides a carefully formatted message, or includes a lot of additional data for debug purposes. So you want to be able to write:

and make it nice and concise. But the compiler writers don't want to have to carefully analyze the code for createReallyDetailedException() to determine exactly what it really does, for all possible inputs. They just want to be able to check the declared return type, and make sure it's some sort of Throwable. Well, and they'll further use that information to determine if the callers of this method are throwing any checked exceptions or not. But that's it.

So what about throw null? Isn't that, like, a case where it's incredibly obvious that the Expression is not resulting in a Throwable instance? Well, yes - but it still would have required an additional rule beyond what's already in the JLS in this section. My guess is that no one ever thought it would be an issue. And since this is the first time we've heard of it being an issue, I guess that wasn't too far from the truth.

Still... wow.
 
Stephan van Hulst
Bartender
Pie
Posts: 6113
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:However I'd also say that a design which requires application code to explicitly throw a NullPointerException is itself questionable. As Sagar says, there are better choices if you have to throw an unchecked exception.

Why? I usually throw a NullPointerException when one of my method arguments is null. I use an InvalidArgumentException when they are otherwise invalid. I think it's pretty clear. NPEs commonly happen when you pass null to a function that doesn't allow null values. As a matter of fact, I find this more clear than using an InvalidArgumentException saying that one of the arguments was null.

Would you say the standard classes are poorly designed because they throw NullPointerExceptions? (Not that they aren't, in some cases).
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not Paul of course, but here are my thoughts:

If (and only if) the problem really is that some method argument was null, then I think it's fine to throw NullPointerException.

If I had designed Java, I'd have preferred to use IllegalArgumentException for this, or perhaps a specific subclass such as NullArgumentException*. I would leave NullPointerException only for things that the JVM throws directly, which basically means that the programmer of the current method screwed up. As opposed to the programmer of the code that called this method, which is what IllegalArgumentException is for. It's a way of saying I didn't screw up; the person who called me did. Of course, that person might still be me - but I'm at least going to try to transfer the blame.

However, at this point, plenty of libraries use NullPointerException to indicate a null argument; it's pretty much the standard Java idiom nowadays. So I would follow this practice rather than try to change it.

I would encourage people to do more than just throwing an NPE though. Give it a meaningful message. In particular, the one thing we generally need to know in order to fix this is: what's the name of the parameter that's null? Give a nice clear message:


* When I mentioned NullArgumentException, I thought I was making it up. Or rather, it's an idea I and others have talked about in the past, but it's not in the standard Java libraries. However it turns out it is in Apache Commons now: org.apache.commons.lang.NullArgumentException. Complete with mandatory name of the null argument. Excellent. So yeah, consider using this.
 
Wouter Oet
Saloon Keeper
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This could be an endless discussion about whether to use NullPointerException or IllegalArgumentException.
I prefer the IllegalArgumentException but apparently the makers of Java prefer NPE. The new Objects.notNull() (Java 7)
throws NPE when its argument is null.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah yes, I forgot about the new Objects utilities. That's the way to go in the future, yes.
 
Stephan van Hulst
Bartender
Pie
Posts: 6113
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I haven't taken a look at all at Java 7. Does anyone have a good link they can recommend that shows the preferred way of doing things in Java 7, over Java 6?

Using Path instead of File, etc.
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Pie
Posts: 15441
41
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Java 7 is being developed in the OpenJDK project. You can download a preview release and documentation from the usual JDK download pages on Oracle's website.

We also have a Java 7/8 forum here on JavaRanch.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic