57

Recently a co-worker of mine wrote in some code to catch a null pointer exception around an entire method, and return a single result. I pointed out how there could've been any number of reasons for the null pointer, so we changed it to a defensive check for the one result.

However, catching NullPointerException just seemed wrong to me. In my mind, Null pointer exceptions are the result of bad code and not to be an expected exception in the system.

Are there any cases where it makes sense to catch a null pointer exception?

Drew
  • 15,158
  • 17
  • 68
  • 77

18 Answers18

37

Yes, catching any RuntimeException is almost always a code smell. The C2 Wiki seems to agree.

An exception would probably be some specially defensive pieces of code which run pretty much random code from other modules. Examples for such defensive structures would be the EDT, ThreadPools/Executors and plugin system.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • 4
    You can imo safely leave that "almost" away. – BalusC Apr 06 '10 at 17:07
  • 5
    @BalusC A place you would want to catch any uncaught exception, including runtime exceptions, would be if you were calling code in a plugin framework and did not want plugin code to cause the entire application to crash. Generically I would say it would be appropriate for code where the code to be called is passed around (i.e. a listener), right? – Joseph Gordon Apr 06 '10 at 17:30
  • 5
    @Joseph: Yes, that makes sense. However, you would in such situation rather like to catch `Exception` or maybe even `Throwable` instead of *specifically* `RuntimeException`. – BalusC Apr 06 '10 at 17:37
  • 10
    Spring has a deep hierarchy of exceptions (all rooted on `RuntimeException`), many of which are emminently catchable (e.g. retry-based data access). Just because you don't *have* to catch it, doesn't mean you *shouldn't* catch it. – skaffman Apr 06 '10 at 19:10
25

I can think of exactly one use for ever catching a NullPointerException:

catch (NullPointerException) {
    ApplyPainfulElectricShockToProgrammer();
}
xlm
  • 6,854
  • 14
  • 53
  • 55
Jeffrey L Whitledge
  • 58,241
  • 9
  • 71
  • 99
15

I have had to catch nullpointer exception sometimes because of a bug in third part library. The library we used threw that exception, and it was nothing we could do about it.

In that case it is OK to catch it, otherwise not.

Shervin Asgari
  • 23,901
  • 30
  • 103
  • 143
  • 3
    I don't find that acceptable. The bug should be reported to the maintainers of that library and they should fix and rebuild asap. If they didn't then it's clearly time to look for another. – BalusC Apr 06 '10 at 17:06
  • 59
    @BalusC: and we *should* have world peace, and free ice cream for all, and a pony... – Derrick Turk Apr 06 '10 at 18:08
  • 1
    @Derrick Turk said it all. Actually the bug was in a major library (JBPM) – Shervin Asgari Apr 07 '10 at 08:34
  • @Shervin: yes but that library has effectively crashed and its internal state may now be inconsistent. The bug should definitely be reported. – JeremyP Jan 17 '11 at 17:16
  • @JeremyP, or the library reloaded, or another appropriate action taken. Maybe the library already IS scheduled for replacement, but not in that point release. Etc... – Prof. Falken Feb 11 '11 at 07:34
  • @Amigable: Or maybe the bug hasn't been reported and the vendors do not know about it. The bug should be reported unless there is evidence that it already has been. – JeremyP Feb 11 '11 at 08:47
  • 5
    The bug was reported, and eventually fixed. It took several months though – Shervin Asgari Oct 15 '11 at 14:34
7

It depends.

How experienced this co-worker is? Is he doing this for ignorance/laziness or is there a real good reason for that? ( like this is the main thread above everything else and should never ever die? )

90% of the times catching a runtime exception is wrong, 99% catching a NullPointerException is wrong ( if the reason is "I was getting a lot of them..." then the whole programmer is wrong and you should look take care for the rest of the code he's doing )

But under some circumstances catching a NullPointerException may be acceptable.

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • 1
    I'd be curious to those "some circumstances". I haven't met them yet in the years I code Java. – BalusC Apr 06 '10 at 17:05
  • 1
    @BaluscC: Think about creating a server whose job when getting a NullPointerException is not to crash, but presenting a error message to the user ( like any decent servlet container ?? ) If they crash when a NpE is thrown from the user, they wouldn't be doing a good job. The main thread of that server shouldn't die by a programmer mistake. – OscarRyz Apr 06 '10 at 17:27
  • Yes, that makes certainly sense. There's however a subtle difference between "catching NullPointerException" and "catching Exception". – BalusC Apr 06 '10 at 17:35
  • @BalusC Indeed, that's just an example to think about it. There may be other reasons depending on the nature of the app ( but 99% of the times it is wrong ) – OscarRyz Apr 06 '10 at 18:01
  • Dear OscarRyz can you please give an example for the 1% where it makes sense to catch a NullPointerException? – Stimpson Cat Sep 30 '16 at 11:51
3

It is bad, but it could produce optimized bytecode.

If Integer i is not null most of the time, then check decreases overall performance. The check itself costs 3 instructions (0-4). The whole case then takes 7 instructions (0-14).

public class IfNotNull {

    public Integer i;

    public String getIAsString() {
        if (i != null) {
            return i.toString();
        } else {
            return "";
        }
    }
}

  public java.lang.String getIAsString();
    Code:
       0: aload_0       
       1: getfield      #2                  // Field i:Ljava/lang/Integer;
       4: ifnull        15
       7: aload_0       
       8: getfield      #2                  // Field i:Ljava/lang/Integer;
      11: invokevirtual #3                  // Method java/lang/Integer.toString:()Ljava/lang/String;
      14: areturn       // <- here we go
      15: ldc           #4                  // String 
      17: areturn 

Following EAFP approach which is common in Python world. The null case will be costly, but we need only 4 instructions (0-7) for not null case.

public class TryCatch {

    public Integer i;

    public String getIAsString() {
        try {
            return i.toString();
        } catch (NullPointerException npe) {
            return "";
        }
    }
}

  public java.lang.String getIAsString();
    Code:
       0: aload_0       
       1: getfield      #2                  // Field i:Ljava/lang/Integer;
       4: invokevirtual #3                  // Method java/lang/Integer.toString:()Ljava/lang/String;
       7: areturn       // <- here we go
       8: astore_1      
       9: ldc           #5                  // String a
      11: areturn       
    Exception table:
       from    to  target type
           0     7     8   Class java/lang/NullPointerException

Who knows, if JIT compiler can optimize this?

PJA
  • 61
  • 3
3

In general, I think it is a code smell; it seems to me that defensive checks are better. I would extend that to cover most unchecked exceptions, except in event loops, etc. that want to catch all errors for reporting/logging.

The exception I can think of would be around a call to a library that can't be modified and which may generate a null pointer exception in response to some assertion failure that is difficult to proactively check.

Michael Ekstrand
  • 28,379
  • 9
  • 61
  • 93
3

Funny

I just found something that shouldn't be done at work:

public static boolean isValidDate(final String stringDateValue) {
    String exp = "^[0-9]{2}/[0-9]{2}/[0-9]{4}$";
    boolean isValid = false;
    try {
        if (Pattern.matches(exp, stringDateValue)) {
            String[] dateArray = stringDateValue.split("/");
            if (dateArray.length == 3) {
                GregorianCalendar gregorianCalendar = new GregorianCalendar();
                int annee = new Integer(dateArray[2]).intValue();
                int mois = new Integer(dateArray[1]).intValue();
                int jour = new Integer(dateArray[0]).intValue();

                gregorianCalendar = new GregorianCalendar(annee, mois - 1,
                        jour);
                gregorianCalendar.setLenient(false);
                gregorianCalendar.get(GregorianCalendar.YEAR);
                gregorianCalendar.get(GregorianCalendar.MONTH);
                gregorianCalendar.get(GregorianCalendar.DAY_OF_MONTH);
                isValid = true;
            }
        }
    } catch (Exception e) {
        isValid = false;
    }
    return isValid;
}

baaad :)

The developper wanted the calendar to raise exceptions of this kind:

java.lang.IllegalArgumentException: DAY_OF_MONTH
    at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2316)
    at java.util.Calendar.updateTime(Calendar.java:2260)
    at java.util.Calendar.complete(Calendar.java:1305)
    at java.util.Calendar.get(Calendar.java:1088)

to invalidate the values...

Yes it works but it's not a really good practice...

Raising exception (particularly filling the stack trace) cost a lot more than just checking data manually without an exception...

Demi
  • 3,535
  • 5
  • 29
  • 45
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
2

It certainly is.

Most of the time, your variables shouldn't be null to begin with. Many new languages are coming out with builtin support for non-nullable reference types -- that is, types which are guaranteed to never be null.

For the times when your incoming value is allowed to be null, you need to do a check. But exceptions are definitively a bad way to do this.

An if statement takes perhaps three instructions to perform and is a local check (meaning, you make the check in the same place as you need the guarantee).

Using an exception, on the other hand, may take many more instructions -- the system attempts to look up the method, fails, looks through the exception table for the appropriate exception handler, jumps there, executes the handler, and jumps again. Furthermore, the check is potentially non-local. If your code is something like this:

try
  return contacts.find("Mom").getEmail()
catch (NullPointerException e)
  return null

You don't know whether the NPE was thrown in 'getEmail' or in 'find'.

A technical worse solution to a very, very common pattern written in a more obfuscated way? It isn't rank, but it definitely smells bad :/

Tac-Tics
  • 1,895
  • 13
  • 19
  • or contacts can be null as well. That is why a programmer should know what he is doing. try / catch AnyException is surely bad style and should not go to production – Stimpson Cat Sep 30 '16 at 11:55
2

The only place you should catch a NullPointerException (or specifically, just any Throwable) is at some top-level or system boundary so that your program doesn't completely crash and can recover. For example, setting up an error page in your web.xml provides a catch-all so that a web application can recover from an exception and notify the user.

GreenieMeanie
  • 3,560
  • 4
  • 34
  • 39
1

What about this:

try
{
    foo.x = bar;
}
catch (NullPointerException e)
{
    // do whatever needs to be done
}

as a micro-optimization when foo may be null, but almost never is?

The idea is this:

  • An explicit NULL check takes a single machine instruction

  • On the other hand, the NULL check in the second version may be done by letting the NULL access occur, catching the SIGSEGV, and throwing a NullPointerException. This is free if the object is not NULL.

Demi
  • 3,535
  • 5
  • 29
  • 45
1

Long ago I had one use. A particularly stupid library would throw NullPointerException when asked for an object in a collection by key and the object was not found. There was no other way to look up than by key and no way to check if the object existed.

Some time later we booted the vendor and started modifying the library. Now the library throws a better exception (my change) and has a check function (somebody else's change).

Of course I'd always end up with exactly one line inside the try block. Any more and I myself would be guilty of bad code.

Demi
  • 3,535
  • 5
  • 29
  • 45
Joshua
  • 40,822
  • 8
  • 72
  • 132
1

Catching a NULL pointer exception really depends on the context ... one should strive to avoid strict absolute rules ... rules should be applied in context - want to trap this exception and put the entire software in some STABLE state - doing nothing or almost next to nothing. All such coding rules should be well understood

At this point you then look at your software AUDIT TRACE ... which you should be doing and discover the SOURCE of this exception.

The idea that a NULL Pointer Exception Shall Never Occur must be verifiable. First do a static analysis ... (which is harder if 3rd party code/components come in) and then do an exhaustive state space search using relevant tools.

x

Xofo
  • 291
  • 1
  • 3
  • 4
1

Catching NPEs (any RTEs in fact) can be necessary to cleanly terminate a Swing-GUI based application.

edit : in this case, it is usually done via a UncaughtExceptionHandler though.

Rhangaun
  • 1,430
  • 2
  • 15
  • 34
0

I try to guarantee results from my interfaces, but if some library or someones code can produce null as a result and im expecting a guarantee catching it might be viable. Ofcourse what you do once you catch it is up to you. Sometimes it just doesnt make sense to check for null, and if you catch it you have some other method of solving the problem that might not be as good but gets the job done.

What im saying is use exceptions for what you can, its a pretty good language feature.

Tore
  • 579
  • 1
  • 6
  • 19
0

Catching a NullPointerException can be useful if your method calls an external interface (or a SOAP API) and there is a possibility that the value returned might be Null. Other than that, there is not a huge benefit to catching these exceptions.

AV.
  • 21
  • 2
0

It really depends on the interface definition. Unstructured NPE handling is as bad as catching Exception or Throwable.

Nulls are useful for identifying an uninitialized state rather than using an empty string or max_int or whatever. Once place where I use null regularly is in places where a callback object is not relevant.

I really like the @Nullable annotation provided by Guice.

http://code.google.com/docreader/#p=google-guice&s=google-guice&t=UseNullable

To eliminate NullPointerExceptions in your codebase, you must be disciplined about null references. We've been successful at this by following and enforcing a simple rule:

Every parameter is non-null unless explicitly specified. The Google Collections library and JSR-305 have simple APIs to get a nulls under control. Preconditions.checkNotNull can be used to fast-fail if a null reference is found, and @Nullable can be used to annotate a parameter that permits the null value.

Guice forbids null by default. It will refuse to inject null, failing with a ProvisionException instead. If null is permissible by your class, you can annotate the field or parameter with @Nullable. Guice recognizes any @Nullable annotation, like edu.umd.cs.findbugs.annotations.Nullable or javax.annotation.Nullable.

Stevko
  • 4,345
  • 6
  • 39
  • 66
0

Yes in Java there is a need to check for a NullPointerException.

Thrown when an application attempts to use null in a case where an object is required. These include:

Calling the instance method of a null object. Accessing or modifying the field of a null object. Taking the length of null as if it were an array. Accessing or modifying the slots of null as if it were an array. Throwing null as if it were a Throwable value.

Applications should throw instances of this class to indicate other illegal uses of the null object.

NullPointerException in other languages when reading text files (i.e. XML), whose records have not been validated to the correct ASCII character and record format.

mpurinton
  • 113
  • 2
  • 3
    Why would you handle it **at runtime**, rather than eliminate any means whereby it could be thrown by doing things right at dev time? – Charles Duffy Apr 06 '10 at 20:49
0

If the programmer is beginner he may have a habit to catch every exception which stops him to get the final output. This should not be entertained by code reviewers.

Catching any RuntimeException is bad. But if it is really necessary then a comment in code will be really helpful for future programmers who will work on that code. If you cannot write a reasonable comment for catching them then you must avoid them. period.

dnsh
  • 3,516
  • 2
  • 22
  • 47