How to avoid Null Pointer Exception in Java

How to avoid Null Pointer Exception in Java

This is a fairly common problem I see with beginning to intermediate programmers. They don't know or trust the conventions they are using, and are careful about checking for null. Also, when they write code, they often rely on returning NULL to indicate some meaning, and therefore require the caller to check for Null.

To put it another way, there are two scenarios where a null pointer check can occur:

A reasonable response in terms of the agreement

Not a reasonable response

The second is very simple, you can use assert or directly allow failure, such as NullPointerException. Assertions are a highly underused feature added since Java 1.4, the syntax is:

  1. assert <condition>

or

  1. assert <condition> : <object>

condition is a boolean expression and object is an object (the output of its toString() method will be included in the error).

If condition is false, assert will throw an Error (AssertionError).

By default Java will ignore assertions. You can enable assertions by passing a -ea parameter to the JVM.

You can enable or disable assertions for a single package or class. This means you can verify your code with assertions during development and testing.

Turn it off when shipping to production, although the tests I show below show no performance loss due to assertions.

This code snippet can be run without assertions, because it will fail just like it would with assertions. The only difference is

With assertions this may happen faster, make more sense, and add some extra information that can help you figure out

Reason for failure.

The first one is a little tricky. If you don't have control over the code being called, you're stuck.

If Null is a reasonable return value, you should check for it.

If it's code you control, it's a completely different story. Try to avoid using NULL as a return value.

For collections that return Collections, it's easy to return Empty (an empty collection or array) instead of always using null as the return value.

For methods that do not return Collections, things get a little more complicated. Consider the following example:

  1. public   interface Action {
  2. void doSomething();
  3. }
  4.  
  5. public   interface Parser {
  6. Action findAction(String userInput);
  7. }

A Parser takes user input as an argument and does something with it (e.g. simulates a command line). Now you might

Returns null if no action corresponding to the input is found, which leads to the null pointer check just mentioned.

An alternative solution is to never return null, but instead return an empty object.

  1. public   class MyParser implements Parser {
  2. private   static Action DO_NOTHING = new Action() {
  3. public   void doSomething() { /* do nothing */ }
  4. };
  5.  
  6. public Action findAction(String userInput) {
  7. // ...  
  8. if ( /* we can't find any actions */ ) {
  9. return DO_NOTHING;
  10. }
  11. }
  12. }

Compare this code:

  1. Parser parser = ParserFactory.getParser();
  2. if (parser == null ) {
  3. // now what?  
  4. // this would be an example of where null isn't (or shouldn't be) a valid response  
  5. }
  6. Action action = parser.findAction(someInput);
  7. if (action == null ) {
  8. // do nothing  
  9. } else {
  10. action.doSomething();
  11. }

and this paragraph:

  1. ParserFactory.getParser().findAction(someInput).doSomething();

This is a better design because it is concise and avoids unnecessary judgment. Even so, it might be more appropriate to have the findAction() method throw an exception with some meaningful error message - especially in this case where you rely on user input. It is much better to have the findAction() method throw an exception instead of simply generating a NullPointerException without any explanation.

  1. try {
  2. ParserFactory.getParser().findAction(someInput).doSomething();
  3. } catch (ActionNotFoundException anfe) {
  4. userConsole.err(anfe.getMessage());
  5. }

Or maybe you think the try/catch mechanism is too ugly and your action should provide a feedback to the user instead of doing nothing:

  1. public Action findAction( final String userInput) {
  2. /* Code to return requested Action if found */  
  3. return   new Action() {
  4. public   void doSomething() {
  5. userConsole.err( "Action not found: " + userInput);
  6. }
  7. }
  8. }

<<:  In-depth understanding of viewport in mobile front-end development

>>:  Greedy UIButton in Swift

Recommend

Lunar Module: The two richest men in the world compete on the lunar surface

On May 19, 2023, NASA announced that it had selec...

Community operation: ten active cases of refined community operation

“Any social network operation that does not obser...

Technology Morning News | Shanghai adds 3 medium-risk areas

【Today’s cover】 Golden rays of light pierce throu...

70-Lecture PPT Quick Guide, Creating a PPT Course Worth $1 Million

Course Catalog: Chapter 1: Xiaobai's Countera...

SMS promotion is ineffective. What is the correct approach to SMS marketing?

In our daily lives, we are overwhelmed by marketi...

How to write copy with user thinking?

Good copywriting is not about expressing your own...

Why does MCN do live broadcasts without selling products?

In the recent live broadcast, there is a breath o...

Four soft methods of app promotion that you may not know!

It is not difficult to develop an APP. The diffic...

What are the main ways to promote apps at home and abroad?

At present, domestic Internet traffic is becoming...

Server rental cloud server rental 618 mid-year promotion discount price

Cloud server BCC intensive computing IC2 CPU Memo...

How can user operations improve referral rates?

Today I would like to talk to you about some thou...