5

I have an unfortunate Java library that I've inherited that parses JSON. Right now, if you ask for a key that doesn't exist in a JSON array, it dies with a null pointer. I'm going to edit the library to do something more reasonable. I think I have two options:

1) Return null so the caller can check

2) Throw a more explicit exception (more descriptive than "Null Pointer"), forcing the caller to handle the case where they asked for a non-existent key.

I come from a python background and am strongly drawn to number 2, seeing as it will ensure that some bonehead can't call this function and then continue on with a null value, crashing their application later on and possibly corrupting data. Which way do YOU think is more in line with best practices of Java? This is not a duplicate of other language-independent questions on the same topic. This is specifically in the context of Java!!!!

ErlVolton
  • 6,714
  • 2
  • 15
  • 26
  • 2
    Number 2 is your best bet. You dont want people looking around taking forever to find the error... – iWumbo Jul 16 '14 at 14:55
  • 1
    This is in a Java-specific context – ErlVolton Jul 16 '14 at 14:57
  • 2
    Really hard to answer. If you're a purist, you shouldn't throw an exception when it is not an exceptional state. If it is perfectly fine that something does not exist (and you end up with a null reference), then you shouldn't throw an exception. – Gimby Jul 16 '14 at 15:04
  • @ErlVolton, yes but the question is kind of language independent ... and more of a design philosopy question ... – DavidPostill Jul 16 '14 at 15:07
  • 2
    Since Java 8 you can also return an `Optional` which is empty in case of a non-existing key. – isnot2bad Jul 16 '14 at 15:09
  • @DavidPostill I don't think so. For example, in Erlang, you would return a tuple like {error, "KeyNotFound"} because that's what OTP says is the correct thing to do. In python, you would throw an exception, because that's a python best practice. The question is how is this situation usually handled in Java – ErlVolton Jul 16 '14 at 15:10

5 Answers5

9

It depends.

Return null so the caller can check

The keyword here is "can". The caller can completely ignore the null value. If this is completely fine, then returning null is fine.

Throw an exception so the caller must check

The keyword is "must". This is the option to take if you think the caller needs to handle the situation.

Throw an unchecked exception so the caller can check

If you do this, then you must have done it very deliberately. Basically, this lets the caller know exactly what went wrong if it does go wrong, but you don't necessarily think they need to (or will even be able to) handle the problem.

Rainbolt
  • 3,542
  • 1
  • 20
  • 44
  • The second part may need to have a small caveat on it, depends on if it's a checked vs unchecked exception, to be "must" anyway. – nerdwaller Jul 16 '14 at 15:04
  • @nerdwaller I think Java will force you to either catch or declare the exception that's declared by a function you are calling. E.g. if getWhatever has "throws MyException" after it, and you are calling getWhatever, the compiler will force you to wrap it in a try block or declare that you "thows MyException" as well. – ErlVolton Jul 16 '14 at 15:06
  • 1
    Actually, throwing an exception doesn't force the caller to check anything, he can simply ignore the exception as he could with a `null`. Except writing more lines to catch it, after that, ignoring it is quite possible. – Jonathan Drapeau Jul 16 '14 at 15:07
  • 2
    @ErlVolton - That's not true. Unchecked Exceptions extend [RuntimeException](http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html) and a method is not obligated to say it throws, nor do most IDEs say you need to catch that. Checked extend Exception, which require you to declare throws on the method, and IDEs will yell at you that you need to catch it. But technically, JonathanDrapeau is correct that you could ignore it, but to do so you need to be deliberate in how you're working and compiling to not see compile errors. – nerdwaller Jul 16 '14 at 15:10
  • @ErlVolton Happy to! I just learned about it last week as I was annoyed that my IDE wasn't telling me I wasn't catching some things I was throwing (which is why I was throwing in the first place!). – nerdwaller Jul 16 '14 at 15:12
  • 1
    @nerdwaller I think I captured the spirit of this comment chain. Let me know if you think something is off about it (particularly the last sentence, which is my own understanding of unchecked exceptions). – Rainbolt Jul 16 '14 at 15:12
  • Very nice answer, great work. – nerdwaller Jul 16 '14 at 15:13
3

This is an esoteric question!

The conventional wisdom is this:-

Don't use exceptions for control flow. Exceptions should be left for when something exceptional happens

This implies returning a NULL and checking for it. i.e. choice (1)

But here is an interesting discussion on this very subject in the context of the Java language.

In a nutshell, as Java's exception system is so flexible, sometimes throwing exceptions and using them to control program flow, can be a sensible way of making the logic of a program more readable and maintainable.

Geeb
  • 631
  • 8
  • 19
  • I've accepted this answer because it pertains directly to Java which is the nature of the question. Thank you! – ErlVolton Jul 16 '14 at 15:17
0

Throw an exception. It gives an explicit explanation of the error that has occurred and allows the program to handle it in an elegant way. This has the advantage of making it much harder to be ignorant of faults that are happening in the program if you are handling these exceptions in a proper fashion (ergo not just catching the exception and doing nothing with it).

JBires
  • 441
  • 3
  • 11
0

I'd always try and throw exceptions so that the coder can easily see what is expected but I can see it being a programmer preference.

If you want to return nulls I would recommend returning Null Objects to avoid awful null pointer exceptions which can plague code and force coders to continually null check because they are never sure whether something returns null or not

RNJ
  • 15,272
  • 18
  • 86
  • 131
0

Of the two options, I would throw an exception, it is an exceptional circumstance (the user is requesting something that doesn't exist) and it's the right thing to do, I think. Some would agree and others as well as 'Clean Code' ... debatably.

Returning null is bad practice -I think- because it just leads to users of the method/class having to deal with a null which can be forgotten and just propagates the null pointer upwards. Some would say this is the right thing to do, however.

The other option in some cases is to return an empty object, avoiding the NullPointerException and not quite classing it as an exceptional situation but I'm not sure that applies here.

Community
  • 1
  • 1
Ross Drew
  • 8,163
  • 2
  • 41
  • 53