11

In java, Which of the following is the more "accepted" way of dealing with possibly null references? note that a null reference does not always indicate an error...

if (reference == null) {
    //create new reference or whatever
}
else {
    //do stuff here
}

or

try {
    //do stuff here
}
catch (NullPointerException e) {
    //create new reference or whatever
}
jmj
  • 237,923
  • 42
  • 401
  • 438
Woodrow Douglass
  • 2,605
  • 3
  • 25
  • 41

11 Answers11

14

The answers already given are excellent (don't use exceptions for control flow; exceptions are expensive to throw and handle). There's one other important reason specifically not to catch NullPointerException.

Consider a code block that does the following:

try {
    reference.someMethod();
    // Some other code
}
catch (NullPointerException e) {
    // 'reference' was null, right? Not so fast...
}

This might seem like a safe way to handle nullity of reference ...but what if reference was non-null and someMethod() raised NPE? Or what if there was a NPE raised elsewhere in the try block? Catching NPE is a surefire way to prevent bugs from being found and fixed.

Alanyst
  • 1,390
  • 7
  • 10
12

Catching exceptions is relatively expensive. It's usually better to detect the condition rather than react to it.

Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
  • 1
    Thanks. I figured "why check for null when the JVM does it for me, i could just use that check", but if catching it is so expensive, i'll just do the check myself. Thanks again! – Woodrow Douglass May 13 '11 at 18:17
7

Of course this one

if (reference == null) {
    //create new reference or whatever
}
else {
    //do stuff here
}

we shouldn't rely on exception for decision making, that aren't given for that purpose at all, also they are expensive.


Well If you aren't making decision and just verifying for initialized variable then

if (reference == null) {
    //create new reference or whatever
}
//use this variable now safely  

I have seen some auto code generator wraps up this thing in accessors/getter method.

jmj
  • 237,923
  • 42
  • 401
  • 438
2

I think in general an exception should be reserved for exceptional circumstances - if a null reference is sometimes expected, you should check for it and handle it explicitly.

dsolimano
  • 8,870
  • 3
  • 48
  • 63
2

From the answers its clear that catching an exception is not good. :) Exceptions are definitely not free of cost. This might help you to understand it in depth. .

I would also like to mention an another practice while comparing your object with a known value.
This is the traditional way to do the job: (check whether the object is null or not and then compare)

Object obj = ??? //We dont know whether its null or not.
if(obj!=null && obj.equals(Constants.SOME_CONSTANT)){
    //your logic
}

but in this way, you dont have to bother about your object:

Object obj = ???
if(Constants.SOME_CONSTANT.equals(obj)){  //this will never throw 
                                          //nullpointer as constant can not be null.
}
Community
  • 1
  • 1
Nirmit Shah
  • 758
  • 4
  • 10
1

The first one, throwing exceptions is a costly operation.

THelper
  • 15,333
  • 6
  • 64
  • 104
1

The first form:

if (reference == null)
{    
    //create new reference or whatever
}
else 
{    
    //do stuff here
}

You should not use exceptions for control flow.

Exceptions are for handling exceptional circumstances that would not normally occur during normal operating conditions.

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
0

You should use exception catching where you do not expect there to be an error. If something can be null, then you should check for that.

Richard H
  • 38,037
  • 37
  • 111
  • 138
0

maybe the try catch approach will start making sense in this situation when we can start doing

try {
  //do stuff here
}
catch (NullPointerException e) {
  //create new reference or whatever
  retry;
}
Martijn
  • 11,964
  • 12
  • 50
  • 96
  • 1
    Not really, you are still throwing an unnecessary exception. Better use `if (reference == null) { // create new reference retry; }` – THelper May 13 '11 at 12:36
0

This is related to your style of development, if you are developing code using "safe" style you have to use

    if(null == myInstance){
// some code    
    }else{
// some code
    }

but if you do not use this style at least you should catch exception, but in this case it NullPointerException and I think preferably to check input parameters to null and not wait to throwing exception.

jitm
  • 2,569
  • 10
  • 40
  • 55
0

Since you asked for Best Practices, I want to point out that Martin Fowler suggests to introduce a subclass for null references as best practice.

public class NullCustomer extends Customer {}

Thus, you avoiding the hassle of dealing with NullPointerException's, which are unchecked. Methods which might return a Customer value of null, would then instead return a NullCustomer instead of null.

Your check would look like:

final Customer c = findCustomerById( id );
if ( c instanceof NullCustomer ) {
    // customer not found, do something ...
} else {
    // normal customer treatment
    printCustomer( c );
}

In my opinion, it is permissible in some cases to catch a NullPointerException to avoid complex checks for null references and enhance code readability, e.g.

private void printCustomer( final Customer c ) {
try {
    System.out.println( "Customer " + c.getSurname() + " " + c.getName() + "living in " +     c.getAddress().getCity() + ", " + c.getAddress().getStreet() );
} catch ( NullPointerException ex ) {
    System.err.println( "Unable to print out customer information.", ex );
}

An argument against it is that by checking for individual members being null, you can write a more detailed error message, but that is often not necessary.

Andreas Krueger
  • 1,497
  • 13
  • 16