【问题标题】:Java : "xx".equals(variable) better than variable.equals("xx") , TRUE?Java : "xx".equals(variable) 比 variable.equals("xx") 好,是吗?
【发布时间】:2010-07-13 19:44:27
【问题描述】:

我正在查看我认为值得怀疑的最佳实践和推荐 Java 编码手册。

推荐:

String variable;

"xx".equals(variable) // OK

variable.equals("xx") //Not recomended

因为防止出现不受控制的 NullPointerException

这是真的吗?

【问题讨论】:

  • 如果您正在编写技术手册,您需要担心的语法问题比像这样的小代码警告要大。
  • @Zak,这并不重要。你怎么知道手册是英文的?也许 Xerg 可以流利地使用其他语言写作,并且正在用该语言编写手册。每个回答的人都设法弄清楚问题的症结所在。
  • 我没有写任何手册。我只是在检查。对不起,我的英语,我是一个比作家更好的读者。

标签: java equals manual


【解决方案1】:

这是一种非常常见的技术,如果变量为空,它会导致测试返回 false,而不是抛出 NullPointerException。但我想我会有所不同,我不会认为这是您应该始终遵循的建议。

  • 我绝对认为这是所有 Java 程序员都应该注意的事情,因为它是一种常见的习惯用法。
  • 这也是一种使代码更简洁的有用技术(您可以同时处理 null 和 not null 的情况)。

但是:

  • 它使您的代码更难阅读:"If blue is the sky..."
  • 如果您刚刚检查过您的参数在上一行中不为空,则没有必要。
  • 如果您忘记测试 null 并且有人确实提供了您没想到的 null 参数,那么 NullPointerException 不一定是最坏的结果。假装一切都好,直到它最终失败,这并不是一个更好的选择。快速失败是好事。

我个人认为在所有情况下都应该使用这种技术。我认为应该由程序员根据具体情况来判断。重要的是确保您以适当的方式处理了 null 案例,并且您如何处理取决于具体情况。检查空值的正确处理可能是测试/代码审查指南的一部分。

【讨论】:

【解决方案2】:

这是真的。如果在您的示例中variablenull

variable.equals("xx");

将抛出 NPE,因为您不能在空对象上调用方法 (equals)。但是

"xx".equals(variable);

只会返回false 而不会出错。

【讨论】:

  • @Tom:好吧,也许吧。我遇到了应该是错误的情况以及许多其他不应该出现的情况。我实际上同意 Mark Byers 的观​​点,即逐案评估它是有意义的。
【解决方案3】:

其实我觉得原来的推荐是真的。如果您使用variable.equals("xx"),那么如果variable 为空,您将获得NullPointerException。将常量字符串放在左侧可以避免这种可能性。

这种防御是否值得许多人认为是不自然的习语的痛苦,这取决于你。

【讨论】:

  • 个人化 我发现“Yoda 版本”读起来很尴尬,但它确实避免了空指针异常。另一种方法是 ' s!=null && s.equals("xx") ',它需要更多的输入,并且需要额外的几纳秒来进行额外的比较。
【解决方案4】:

这是 Java(和 C#)程序中常用的技术。第一种形式避免了空指针异常,因为在常量字符串"xx" 上调用了.equals() 方法,该字符串永远不会为空。与 null 相比,非 null 字符串为 false。

如果您知道variable 永远不会为空(如果您的程序为空,那么您的程序在其他方面不正确),那么使用variable.equals("xx") 就可以了。

【讨论】:

    【解决方案5】:

    确实,以这种方式使用对象的任何属性都可以帮助您避免 NPE。

    但这就是为什么我们有例外来处理这类事情。

    也许如果你使用 "xx".equals(variable) 你永远不会知道变量的值是 null 还是不等于 "xx"。 IMO 最好知道您在变量中获得了一个空值,因此您可以对其重新签名,而不是仅仅忽略它。

    【讨论】:

      【解决方案6】:

      您对检查的顺序是正确的——如果变量为空,在字符串常量上调用 .equals 将阻止 NPE——但我不确定我是否认为这是一个好主意;我个人称之为“slop”。

      Slop 是指您没有检测到异常情况,但实际上养成了个人习惯以避免检测到异常情况。将 null 作为字符串传递很长一段时间最终会导致可能晦涩难懂的错误。

      为 slop 编码与“Fail fast fail hard”相反。

      使用空值作为字符串偶尔会产生一个很好的“特殊”值,但你试图将它与某物进行比较这一事实表明你对系统的理解是不完整的(充其量)——你越早发现这个事实出来,更好。

      另一方面,默认情况下将所有变量设为最终变量、使用泛型并最小化所有对象/方法的可见性是减少浪费的习惯。

      【讨论】:

        【解决方案7】:

        如果您需要检查null,我发现这比 if (variable != null && variable.equals("xx"))。这更多的是个人喜好问题。

        【讨论】:

          【解决方案8】:

          附带说明,这是一个设计模式,此代码推荐可能没有任何区别,因为字符串(即Optional<String>)永远不会为空,因为来自设计模式的 .isPresent() 调用:

          Optional<String> gender = Optional.of("MALE");
          if (gender.isPresent()) {
              System.out.println("Value available.");
          } else {
              System.out.println("Value not available.");
          }
          gender.ifPresent(g -> System.out.println("Consumer: equals: " + g.equals("whatever")));
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-04-06
            • 1970-01-01
            • 2022-11-12
            • 2011-12-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多