【问题标题】:Java Object Null Check for methodJava Object Null 检查方法
【发布时间】:2014-03-07 00:47:26
【问题描述】:

我需要在此公式中为书籍 [i] 创建一个空值检查,但我不完全确定如何执行此操作,因为我对空值检查不是很熟悉并且在编程方面非常陌生。非常感谢任何和所有帮助!

public static double calculateInventoryTotal(Book[] books)
{
    double total = 0;

    for (int i = 0; i < books.length; i++)
    {
        total += books[i].getPrice();
    }

    return total;
}

【问题讨论】:

  • if(books[i] != null) ?

标签: java null-check


【解决方案1】:
public static double calculateInventoryTotal(Book[] arrayBooks) {

    final AtomicReference<BigDecimal> total = new AtomicReference<>(BigDecimal.ZERO);
    Optional.ofNullable(arrayBooks).map(Arrays::asList).ifPresent(books -> books.forEach(book -> total.accumulateAndGet(book.getPrice(), BigDecimal::add)));
    return total.get().doubleValue();

}

【讨论】:

    【解决方案2】:

    这个问题比较老了。此时提问者可能已经变成了一位经验丰富的 Java 开发人员。但是我想在这里添加一些对初学者有帮助的意见。

    对于 JDK 7 用户,这里使用

    Objects.requireNotNull(object[, optionalMessage]);
    

    不安全。如果此函数找到null 对象并且它是RunTimeException,则抛出NullPointerException

    这将终止整个程序!!。所以最好使用==!= 来检查null

    另外,使用List 代替Array。虽然访问速度相同,但使用Collections 而不是Array 有一些优势,比如如果您以后决定更改底层实现,您可以灵活地进行。例如,如果您需要同步访问,您可以将实现更改为Vector,而无需重写所有代码。

    public static double calculateInventoryTotal(List<Book> books) {
        if (books == null || books.isEmpty()) {
            return 0;
        }
    
        double total = 0;
    
        for (Book book : books) {
            if (book != null) {
                total += book.getPrice();
            }
        }
        return total;
    }
    

    另外,我想对@1ac0 的回答投赞成票。 我们在写作时也应该理解和考虑方法的目的。调用方法可以根据被调用方法返回的数据进一步实现逻辑。

    此外,如果您使用 JDK 8 进行编码,它引入了一种新的方法来处理 null 检查并保护代码免受NullPointerException 的影响。它定义了一个名为Optional 的新类。 Have a look at this for detail

    最后,请原谅我的英语不好。

    【讨论】:

      【解决方案3】:

      首先你应该检查books本身是否不为空,然后简单地检查books[i] != null是否:

      if(books==null) throw new IllegalArgumentException();
      
      for (int i = 0; i < books.length; i++){
         if(books[i] != null){
              total += books[i].getPrice();
         }
      }
      

      【讨论】:

      • 你试过用 null 作为书籍的输入值吗?
      • @ladislavDANKO 谢谢,我最初只回答 OP 的要求,但这是一个很好的评论!编辑了我的答案。
      • 老式编程,请更新到 Java 8,请参阅下面的评论。 (更糟糕的是答案不正确,你不要使用 double 进行货币计算,这是 BigDecimal 的工作)
      【解决方案4】:

      如果 Books 数组为 null,则返回零,因为它看起来该方法计算提供的所有 Books 的总价格 - 如果没有提供 Books,则零是正确的值:

      public static double calculateInventoryTotal(Book[] books)
      {
      if(books == null) return 0;
          double total = 0;
          for (int i = 0; i < books.length; i++)
          {
              total += books[i].getPrice();
          }
          return total;
      }
      

      您可以决定输入空输入值是否正确(应该不正确,但是...)。

      【讨论】:

      • 正确的结果是什么 0?一般来说,异常或null(通过自动装箱返回类型)比使用幻数更受欢迎。
      • @BrianRoach 看起来calculateInventoryTotal(Books[] books) 计算了所提供图书的总价。因此,如果没有提供图书,则总价为零。所以在这种情况下 0 是正确的返回值,它绝对不是幻数。
      • 你如何区分传入的null 数组和包含一本/全部书的价格为0 的数组?抛出 IllegalArgumentException 是更好选择的原因是因为它可以防止两种不同的情况(一种有效,一种无效)产生相同的结果,并明确指示编程错误。
      • @BrianRoach 你需要区分这个吗?在假设的方法calculateInventoryCount(Book[] books) 中,您应该需要这个,但如果您需要总价 - 在现实世界中价格应该为零或高于零,如果您没有书或有数百本书,这无关紧要。这取决于你的分析;-)
      • 请注意,我并没有否决您的答案或任何内容,我只是认为向初学者解释最佳实践方法很重要,而不是现在对他们正在做的事情有效.请注意,OP 实际上已经接受了解释最少的答案 ::sigh::
      【解决方案5】:

      如果您使用的是 Java 7,您可以使用 Objects.requireNotNull(object[, optionalMessage]); - 检查参数是否为 null。要检查每个元素是否不为空,只需使用

      if(null != books[i]){/*do stuff*/}
      

      例子:

      public static double calculateInventoryTotal(Book[] books){
          Objects.requireNotNull(books, "Books must not be null");
      
          double total = 0;
      
          for (int i = 0; i < books.length; i++){
              if(null != book[i]){
                  total += books[i].getPrice();
              }
          }
      
          return total;
      }
      

      【讨论】:

      • Yoda 测试在 java 中没有价值:只需正常编码为 if (books == null)
      • 如果你只用 java 编码,它们可能没有任何价值,但如果你用一种以上的语言编程,其中存在差异,yoda 检查非常重要并很快成为一种习惯。我发现它们更具可读性:)
      • 但这是一个 java 问题,没有人在 java 中使用它们。这是行业标准。
      • ::举手:: 我用它们。因为习惯(一个,坦率地说,我不想打破,因为我是一个多语种)。而且我愿意打赌我不是唯一一个;)
      【解决方案6】:

      您可以在方法中添加保护条件以确保books 不为空,然后在迭代数组时检查是否为空:

      public static double calculateInventoryTotal(Book[] books)
      {
          if(books == null){
              throw new IllegalArgumentException("Books cannot be null");
          }
      
          double total = 0;
      
          for (int i = 0; i < books.length; i++)
          {
              if(books[i] != null){
                  total += books[i].getPrice();
              }
          }
      
          return total;
      }
      

      【讨论】:

        【解决方案7】:

        您只需使用==(或!=)运算符将您的对象与null 进行比较。例如:

        public static double calculateInventoryTotal(Book[] books) {
            // First null check - the entire array
            if (books == null) {
                return 0;
            }
        
            double total = 0;
        
            for (int i = 0; i < books.length; i++) {
                // second null check - each individual element
                if (books[i] != null) {
                    total += books[i].getPrice();
                }
            }
        
            return total;
        }
        

        【讨论】:

        • 正确的结果是什么 0?一般来说,异常或null(通过自动装箱返回类型)比使用幻数更受欢迎。
        • 这只是对空值的正确检查:首先检查数组,然后检查每个元素。
        【解决方案8】:

        在你的 for 循环中,只需添加以下行:

        if(books[i] != null) {
             total += books[i].getPrice();
        }
        

        【讨论】:

        • 公平点;如果books 参数为null,则会出现NullPointerException,但我不认为这是提问者所说的null 检查类型。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-18
        • 2020-11-07
        • 1970-01-01
        • 1970-01-01
        • 2011-06-01
        • 1970-01-01
        相关资源
        最近更新 更多