5

It seems like it is not a good idea to catch a nullpointerexception. If that's the case, why is it thrown by methods? Should it just be caught with Exception?

Also, if I encounter a parameter which is null (can either be primitive type like string or a class with fields), how should I handle it? (assumingly not throw npe)?

Thanks

snakile
  • 52,936
  • 62
  • 169
  • 241
GurdeepS
  • 65,107
  • 109
  • 251
  • 387
  • 3
    String is not primitive type, fyi. – fmucar Jan 17 '11 at 16:44
  • 1
    String can be null, but a primitive type like `int` cannot. – Peter Lawrey Jan 17 '11 at 16:45
  • 1
    It's thrown by methods because someone (read: you) are passing nulls to it. It's best to avoid nulls at all times, and/or scatter your application with null checks. Prefer using empty strings, the Null Object pattern, andsoforth. – cthulhu Jan 18 '11 at 11:25
  • https://www.securecoding.cert.org/confluence/display/java/ERR08-J.+Do+not+catch+NullPointerException+or+any+of+its+ancestors – Arto Bendiken Oct 28 '14 at 23:28

7 Answers7

15

It is a runtime exception, thus is not intended to be caught deep inside your program code, only [update] at (or close to) the top level or [/update] by the JVM. Since runtime exceptions signal serious problems (typically grave programming errors, configuration/integration problems etc.), it is best to let them propagate to the top, which typically makes the whole thread fail spectacularly. This gives a strong signal that something is wrong and needs to be fixed ASAP.

See also Is Catching a Null Pointer Exception a Code Smell?.

Also, if I encounter a parameter which is null [...], how should I handle it?

It is OK to throw a NPE in general. However, depending on the circumstances, you may also consider IllegalArgumentException, or using an assertion. See also

Community
  • 1
  • 1
Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 1
    +1 However, I think the statement that runtime exceptions are not intended to be caught within program code is subjectively wrong. The concept of a fault barrier exists specifically to protect the everyday user from seeing a stacktrace. – Tim Bender Jan 17 '11 at 18:08
  • @Tim, you are right, I was sloppy with this. I fixed the text above. Thanks :-) – Péter Török Jan 18 '11 at 08:22
6

A nullpointerexception usually indicates a programmer error. You won't catch a null pointer exception if you don't expect such a programmer error. For instance, say you implement a method myMethod with one parameter of type P.

void myMethod(P x)

Let's say you don't expect the parameter x to be null. In this case you might not check for null. Why? because you assume that the programmer who is using your method will use it properly and won't pass null. I'm not saying whether you should or shouldn't check for null in such cases. I'm just trying to answer why sometimes a null pointer exception is thrown by a method and isn't supposed to be caught. Here's why: Your method might throw a null pointer exception because someone didn't use it right (passed null). The programmer who is using your method might know that if the method is being used wrong it might throw a nullpointerexcetption. But even if he uses your method wrong the exception won't be caught because everyone assumes that the method isn't misused.

Your second question: First, a String is an Object, not a primitive type. Second, primitives can't be null (primitives are ints, doubles, floats, chars, booleans and some others). Now, if you encounter a parameter which is null and it shouldn't be null (in other words you received an illegal argument) you have some choices:

  • Throw an IllegalArgumentException indicating the parameter is null and your method expects it not to be null.
  • Don't do anything. Assume your method is being used correctly (in other words, assume no programmer errors).
  • Use assertions: assert(x != null);

I personally am not a fan of defensive programming and usually prefer the second option. But still, if I want to ensure some invariants on my variables I'm using assertions. But these are just my habits and others probably disagree.

snakile
  • 52,936
  • 62
  • 169
  • 241
  • Note that it's sometimes considered good or better practice to throw an NPE instead of an IllegalArgumentException in the case of a null argument. But that's probably more an argument of personal preferences - a null can also be considered an illegal argument. – cthulhu Jan 18 '11 at 11:26
4

This answer may be lengthy but I think it worth it.

It seems like it is not a good idea to catch a nullpointerexception.

You're right, you should not catch NullPointerException, nor any runtime exception.

If that's the case, why is it thrown by methods? Should it just be caught with Exception?

It is used to indicate a programming error was found. These programming errors could and should be fixed with code ( That is, they're preventable )

Also, if I encounter a parameter which is null how should I handle it? [...](assumingly not throw npe)?

It depends on what you want to do with it. For some logic, a null value may be allowed. If that's the case, you validate the presence of null and do something about it, either provide a default value or avoid sending messaged to the null.

For instance. Let's say you have a billing information system, and you have this code where you save the customer information, and you may optionally save customer extra information.

In this case, the optional message may be null, and your code should validate the presence of it.

For instance:

/**
* ...
* @param - OptionalMessage may be null, include anything else you wan to save.
*/
public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
   SomeMessage message = SomeMessage.createMessage();
   message.setHeader( c.name() );
   message.setCustomerInformation( c );
   if( optionalMessage != null ) { // is optional? handle it
      message.add( optionalMessage.status() );
      message.add( optionalMessage.summary() );
      message.add( optionalMessage.message() );
    }
 }

}

You validate the presence of null and document it.

But this same code also has a customer as parameter, in this case you could:

a) Do nothing b) Validate it also c) Throw a different exception according to the level of abstraction at this level.

For instance, the above code, does a) nothing. This will result in a NullPointerException where the code c.name() is invoked, and this should be catched early in the development tests. Also, it should be documented, in the param and the throws in the javadoc.

/**
 * ...
 * @param  c - The customer whose information is to be sent. NotNull 
 * ...
 * @throws NullPointerException if the customer is null
 */
public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
   SomeMessage message = SomeMessage.createMessage();
   ...

If somebody invokes this method with a null, the Npe will indicate they have coded something wrong. Plus, the Npe, will say very quickly what and where the coding error was ( when invoking the sendCustomerInformation with null customer.

option b) Validate it. It may be the case, when you may allow to handle a null customer ( it doesn't make sense but, it is an option )

In this case you may validate it and return prematurely ( in a I'm done fashion )

public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
   if( cusomer == null ) {  return; // I'm done! } 
   // else 
   SomeMessage message = ... 
   ..
}

Or may create a replacement:

public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
   if( cusomer == null ) {  c = new EmptyCustomer() ;} 
   // else 
   SomeMessage message = ... 
   ..
}

option c) This is similar to a, but, in this case you throw the exception according to the level of abstraction. For instance, if this is going to be shown to the final user in a GUI or something, it may not make sense to just throw the Npe:

public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
   if( cusomer == null ) {  
     // oh oh  something went wrong. 
     log.fatal("Invalid argument on \"sendCustomerInformation\" );
     throw new MyApplicationException("Dear customer, the information yada yaa"); 
   } 
   ...

If this is some sort of invalida state in the app:

public void sendCustomerInformation( Customer c , OptionalMessage optionalMessage ) { 
   if( cusomer == null ) {  
     // wait a minute, how could... why did.. what?
     throw new IllegalStateException("Hey, I got null on sendCustomerInformation and this shouldn't happen");
   }
   ...

Because maybe the app is responsible to keep that object/parameter in a valid shape.

Conclusion

So it depends on the scenario, but in general terms, a NullPointerException ( and most RuntimeExceptions ) indicate something that could be fixed with code ( that are a programmer mistake ) and you can always do something about it. There are cases where you can't do something about it, the best thing you can do, is to let it pop.

I hope this helps.

See also: Exception other than RuntimeException

Community
  • 1
  • 1
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
2

Throw an IllegalArgumentException rather than a NP if someone illegally passes Null to your method. That better describes the error.

Speck
  • 2,259
  • 1
  • 20
  • 29
1

NPE and RuntimeExceptions in general are mostly thrown when there's a coding error, that's why catching them isn't considered to be a good idea. What should be done instead is fixing the code that can't handle the null input.

Which is the second part of your question, how null input should be handled. It depends entirely on what you're reasonably expecting in your code.

Let's say that you read data from a database table and read a null value from a nullable column, that's definitely not an exceptional case, so your code should handle it as its appropiate from a business point of view (e.g. ignore the entire row, prompt the user to enter a value or just use a dummy value).

However if you're reading a null value from a non-nullable column, say a primary key, you should throw an application-specific exception, which is (hopefully) handled by your application's UI.

So the answer is really as simple as: if null is a value that can happen during normal operation, deal with it accordingly, if not, throw a checked business exception instead of an NPE.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • 1
    Also, if "null input" refers to null arguments passed into a method that doesn't expect them to be nullable, then an NPE is appropriate; see Guava's `Precondition.checkNotNull`. It's good practice to do so in public APIs as it immediately shows the programmer that they used the API incorrectly. – ide Jan 17 '11 at 16:48
  • True, if you are writing a third party library, throwing NPE may be appropiate, I was focusing on "end user" code. – biziclop Jan 17 '11 at 16:52
1

The most probable circumstances under which you might want to catch an NPE is when you are implementing a kind of framework, that is, you do NOT want to terminate your application, but report the error, and you have a way of (sensibly) continue in your application.

Volker Stolz
  • 7,274
  • 1
  • 32
  • 50
0

To avoid null-checks in your code, in most cases it's appropriate to return a null-object or an empty list/map/set instead of null.

Claude
  • 453
  • 2
  • 9