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