How to avoid checking for null values in method chaining?

This question already has an answer here:

  • Null check chain vs catching NullPointerException 19 answers
  • Avoiding != null statements 58 answers

  • No, it is generally not good practice in Java to catch a NPE instead of null-checking your references.

    You can use Optional for this kind of thing if you prefer:

    if (Optional.ofNullable(country)
                .map(Country::getCity)
                .map(City::getSchool)
                .map(School::getStudent)
                .isPresent()) {
        isValid = true;
    }
    

    or simply

    boolean isValid = Optional.ofNullable(country)
                              .map(Country::getCity)
                              .map(City::getSchool)
                              .map(School::getStudent)
                              .isPresent();
    

    你可以在这里使用Optional ,但是它在每一步创建一个Optional对象。

    boolean isValid = Optional.ofNullable(country)
        .map(country -> country.getCity()) //Or use method reference Country::getCity
        .map(city -> city.getSchool())
        .map(school -> school.getStudent())
        .map(student -> true)
        .orElse(false);
    
    //OR
    boolean isValid = Optional.ofNullable(country)
                          .map(..)
                          ....
                          .isPresent();
    

    The object-oriented approach is to put the isValid method in Country and the other classes. It does not reduce the amount of null checks, but each method only has one and you don't repeat them.

    public boolean isValid() {
      return city != null && city.isValid();
    }
    

    This has the assumption that validation is the same everywhere your Country is used, but typically that is the case. If not, the method should be named hasStudent(), but this is less general and you run the risk of duplicating the whole School interface in Country. For example, in another place you may need hasTeacher() or hasCourse().

    Another approach is to use null objects:

    public class Country {
      public static final Country NO_COUNTRY = new Country();
    
      private City city = City.NO_CITY;
    
      // etc.
    }
    

    I'm not sure it is preferable is this case (strictly you would need a sub class to override all modification methods), the Java 8 way would be to go with Optional as method in the other answers, but I would suggest to embrace it more fully:

    private Optional<City> city = Optional.ofNullable(city);
    
    public Optional<City> getCity() {
       return city;
    }
    

    Both for null objects and Nullable only work if you always use them instead of null (notice the field initialization), otherwise you still need the null checks. So this option avoid null, but you code becomes more verbose to reduced null checks in other places.

    Of course, the correct design may be to use Collections where possible (instead of Optional). A Country has a set of City, City has a set of Schools, which has set of students, etc.

    链接地址: http://www.djcxy.com/p/13292.html

    上一篇: 如何避免Java中的多个IF循环

    下一篇: 如何避免检查方法链中的空值?