头图
Translator: lizeyang Source of this article: blog.csdn.net/lizeyang/article/details/40040817

problem

In order to avoid null pointer calls, we often see statements like this

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

In the end, there will be a lot of null code in the project, how ugly and cumbersome! How to avoid this situation? Have we abused the penalty?

Reply

This is a problem often encountered by beginner and intermediate programmers. They always like to return null in methods, so when calling these methods, they also have to judge null. In addition, perhaps affected by this habit, they always subconsciously believe that all returns are untrustworthy. In order to protect their own procedures, they have added a lot of empty space.

After vomiting, return to the subject itself and make an unprecedented judgment. Please distinguish the following two situations:

  • Null is a valid and meaningful return value (Where null is a valid response in terms of the contract; and)
  • Null is invalid and wrong (Where it isn't a valid response.)

You may not understand the meaning of these two sentences. Don't worry, continue to read on. Next, we will discuss these two situations in detail.

Let me talk about the second case first

Null is an unreasonable parameter, so the program should be explicitly interrupted and errors should be thrown out. This situation is common in api methods. For example, if you develop an interface, id is a required parameter. If the caller does not pass this parameter to you, of course it will not work. You have to perceive this situation and tell the caller "Hey, buddy, you pass a null to me."

Compared with empty sentences, there are two better ways to check

  • In the assert statement, you can put the cause of the error in the argument of the assert, which not only protects your program from going down, but also returns the cause of the error to the caller. Wouldn’t it kill two birds with one stone? (The original text introduces the use of assert, omitted here)
  • You can also throw a null pointer exception directly. As mentioned above, null is an unreasonable parameter at this time. If there is a problem, there is a problem, and it should be thrown out generously.

first case will be more complicated

In this case, null is a "seemingly" reasonable value. For example, when I query a database, there is no corresponding value under a certain query condition. In this case, null can be regarded as expressing the concept of "empty".

Here are some practical suggestions:

  1. If the return type of the method is collections

When the return result is empty, you can return an empty collection (empty list) instead of returning null. This way the caller can boldly handle the return. For example, after the caller gets the return, you can directly print list.size( ), and there is no need to worry about the null pointer problem. (What? When I want to call this method, I don’t remember whether the method was implemented in accordance with this principle? So, code habit is very important! If you develop a habit, you write code like this (returning empty collections instead of returning null), When you call a method written by yourself, you can boldly ignore the nullity)

  1. What if the return type is not collections?

Then return an empty object (not a null object), the following is a "chestnut", assuming the following code

public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}

Among them, Parse has an interface FindAction, which will find and execute corresponding actions based on user input. If the user input is incorrect, the corresponding action (Action) may not be found, so findAction will return null, and then when the action calls the doSomething method, a null pointer will appear.

One way to solve this problem is to use the Null Object pattern (empty object pattern)

Let's transform

The class definition is as follows. After defining the findAction method in this way, ensure that no matter what the user inputs, no null object will be returned:

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;
    }
  }
}

Compare the following two call examples

1. Redundancy: Every time an object is acquired, it is judged as empty

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();
}

2. Streamline

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

Because no matter what the situation, it will not return an empty object, so after getting the action through findAction, you can safely call the action method.

Other selected answers:

  1. If you want to use the equal method, please use object<may be empty>.equal(object<may be empty>))
    For example: use

    "bar".equals(foo)

Instead of

foo.equals("bar")
  1. In Java8 or guava lib, the Optional class is provided, which is an element container. Objects can be encapsulated through it, which can reduce null judgment. However, the amount of code is still a lot. accurate.
  2. If you want to return null, please stop and think about whether this place should throw an exception.

stackoverflow link:
http://stackoverflow.com/questions/271526/avoiding-null-statements-in-java?page=2&tab=votes#tab-top

against the front started to write is a focus on technology platform programmer circle, you can harvest the latest technological developments, latest Niece qualifications, experience BAT and other manufacturers Gangster, growth itself, learning materials, career path , thinking of making money, WeChat search counterfeit start to pay attention!

code小生
165 声望18 粉丝