代码之家  ›  专栏  ›  技术社区  ›  Brad Parks

如果中间的所有对象都存在,是否对链式可选方法调用java方法?[副本]

  •  0
  • Brad Parks  · 技术社区  · 4 年前

    我需要检查某个值是否为null。如果不是null,那么只需将某个变量设置为true。这里没有其他声明。我有太多这样的状况检查。

    有没有办法在不检查所有方法返回值的情况下处理此空检查?

    if(country != null && country.getCity() != null && country.getCity().getSchool() != null && country.getCity().getSchool().getStudent() != null .....) {
        isValid = true;
    }
    

    我考虑直接检查变量并忽略它 NullpointerException

    try{
        if(country.getCity().getSchool().getStudent().getInfo().... != null)
    } catch(NullPointerException ex){
        //dont do anything.
    }
    
    0 回复  |  直到 3 年前
        1
  •  80
  •   khelwood Muhammed Elsayed.radwan    6 年前

    不,在Java中,捕获NPE而不是空检查引用通常不是好的做法。

    你可以用 Optional

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

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

    如果仅此而已 isValid 应该是在检查。

        2
  •  16
  •   Thiyagu    7 年前

    你可以用 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();
    
        3
  •  7
  •   Walter Laan    7 年前

    面向对象的方法是将isValid方法放在Country和其他类中。它不会减少空检查的数量,但是每个方法只有一个,并且您不会重复它们。

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

    另一种方法是使用空对象:

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

    我不确定在这种情况下是否更可取(严格来说,您需要一个子类来覆盖所有修改方法),Java 8的方法是在其他答案中使用Optional as方法,但我建议更全面地接受它:

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

    当然,正确的设计可能是在可能的情况下使用集合(而不是可选的)。一个国家有一套城市,一个城市有一套学校,其中有一套学生,等等。

        4
  •  5
  •   davidxxx    7 年前

    作为其他精细用途的替代品 Optional Supplier<Object> 变量args作为参数。
    这是有道理的,因为我们在对象中没有很多嵌套级别要检查,但有很多字段要检查。
    此外,它还可以很容易地修改为作为一个日志记录/处理某个内容 null

        boolean isValid = isValid(() -> address, // first level
                                  () -> address.getCity(),   // second level
                                  () -> address.getCountry(),// second level
                                  () -> address.getStreet(), // second level
                                  () -> address.getZip(),    // second level
                                  () -> address.getCountry() // third level
                                               .getISO()
    
    
    @SafeVarargs
    public static boolean isValid(Supplier<Object>... suppliers) {
        for (Supplier<Object> supplier : suppliers) {
            if (Objects.isNull(supplier.get())) {
                // log, handle specific thing if required
                return false;
            }
        }
        return true;
    }
    

    假设您想添加一些跟踪,您可以这样写:

    boolean isValid = isValid(  Arrays.asList("address", "city", "country",
                                              "street", "zip", "Country ISO"),
                                () -> address, // first level
                                () -> address.getCity(),   // second level
                                () -> address.getCountry(),// second level
                                () -> address.getStreet(), // second level
                                () -> address.getZip(),    // second level
                                () -> address.getCountry() // third level
                                             .getISO()
                             );
    
    
    @SafeVarargs
    public static boolean isValid(List<String> fieldNames, Supplier<Object>... suppliers) {
        if (fieldNames.size() != suppliers.length){
             throw new IllegalArgumentException("...");
        }
        for (int i = 0; i < suppliers.length; i++) {
            if (Objects.isNull(suppliers.get(i).get())) {
                LOGGER.info( fieldNames.get(i) + " is null");
                return false;
            }
        }
        return true;
    }
    
        5
  •  4
  •   vikingsteve    7 年前

    Java没有“空安全”操作,例如 Kotlin's null safety

    您可以:

    • 手动检查所有引用
    • 根据其他答案使用可选选项

    否则,如果您可以控制域对象,则可以重新设计类,以便从顶级对象(make)获得所需的信息 Country

        6
  •  0
  •   6harat    7 年前

    您还可以看看vavr的选项,正如下面的文章所描述的,它比Java的可选选项更好,并且具有更丰富的API。

    https://softwaremill.com/do-we-have-better-option-here/