The article was first published on the bulletin board of the public account Songhua Preserved Egg

The author works for JINGdong, and has an in-depth understanding of stability assurance, agile development, advanced JAVA, and microservices architecture

To avoid null pointer calls, we often see statements like this

if(someobject ! = null) { someobject.doCalc(); }Copy the code

You end up with a lot of null-detection code in your project, which is ugly and cumbersome! How can this be avoided? Have we abused short calls?

This is a common problem for early and intermediate programmers. They always like to return null in their methods, so they have to nullify those methods when they are called. In addition, perhaps influenced by this habit, they subconsciously believe that all returns are untrustworthy and add a lot of nullates to protect their program.

After teasing, return to the topic itself and judge unprecedented, please distinguish the following two cases:

  1. Null is a valid and meaningful return value
  2. Null is invalid and incorrect

If you don’t know what these two sentences mean, don’t worry, read on and we’ll discuss both cases in detail

In the second case, null is an invalid argument and should explicitly interrupt the program and throw out an error. This is often the case with API methods. For example, if you develop an interface, id is a mandatory parameter, if the caller does not pass this parameter to you, of course not. You have to sense this and tell the caller “Hey, dude, what are you doing passing null to me?”

There are two better ways to check for null statements

  1. Assert statements. You can use the assert argument to protect your program from falling and to return the error reason to the caller.
  2. You can also throw a null-pointer exception directly. In this case, null is an invalid parameter. If there is a problem, it should be thrown out.

Case 1 is a little more complicated. In this case, null is a “seemingly” reasonable value. For example, if I am querying a database and there is no value for a particular query, null is the definition of null.

Here are some practical tips:

  • If the method return type is collections, you can return an empty collections (empty list) instead of null if the result is empty. This allows the caller to handle the return boldly. For example, the caller can print list.size() without worrying about null Pointers.
  • What if the return type is not Collections? Return an empty object (instead of a null object), for example, assuming the following code
public interface Action {
  void doSomething(); } public interface Parser { Action findAction(String userInput); }Copy the code

Parse has an interface, FindAction, that finds and executes actions based on user input. If the user typed something wrong, the Action might not be found, so findAction returns null, and then when the Action calls the doSomething method, the null pointer will appear. One way to solve this problem is to use Null Object pattern.

Let’s reinvent it

The findAction method is defined to ensure that no null object is returned regardless of what the user enters:

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) { return DO_NOTHING; }}}Copy the code

Compare the two invocation examples below

  1. Redundancy: Null is declared every time an object is retrieved
Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing} 
else{ action.doSomething(); }Copy the code

  1. streamline
ParserFactory.getParser().findAction(someInput).doSomething();Copy the code

Because no empty object is returned in any case, you can safely call the action’s methods once you get the action in findAction.

Other:

  • If you want to use the equal method, use object< cannot be empty >. Equal (object< may be empty >)) for example: use"bar".equals(foo) Rather thanfoo.equals("bar")
  • Java8, or guava lib, provides the Optional class, which is an element container that encapsulates objects to reduce nulls. But it’s still a lot of code. Not great.
  • If you want to return NULL, stop and think about whether this would be a better place to throw an exception.

Source: www.liangsonghua.me

Liang Songhua, senior engineer of JINGdong, has an in-depth understanding of stability assurance, agile development, JAVA advanced and micro-service architecture