Java 为什么myString.equals(“aString”);不同于;阿斯林;。等于(myString);?

Java 为什么myString.equals(“aString”);不同于;阿斯林;。等于(myString);?,java,string,equals,Java,String,Equals,我多次听说,在使用布尔等于(对象o)来比较字符串时,最好将常量放在函数的左侧,如下所示: 坏:myString.equals(“aString”) 好:“aString”。等于(myString) 这是为什么?因为如果myString为空,则会出现异常。您知道“aString”永远不会为空,因此可以避免该问题 您经常会看到库使用nullSafeEquals(myString,“aString”)

我多次听说,在使用
布尔等于(对象o)
来比较
字符串时,最好将常量放在函数的左侧,如下所示:

  • 坏:myString.equals(“aString”)
  • 好:“aString”。等于(myString)

这是为什么?

因为如果
myString
为空,则会出现异常。您知道
“aString”
永远不会为空,因此可以避免该问题


您经常会看到库使用
nullSafeEquals(myString,“aString”)NullPointerException
s。如果常数总是在左边,那么在
等于
调用上就不可能得到NPE。

这是一个糟糕的设计,因为你隐藏了NullPointerException。您将看到一些奇怪的程序行为,并在其他地方引发异常,而不是收到字符串为null的警报


但这一切都取决于“null”是否是字符串的有效状态。一般来说,“null”永远不应该被认为是传递的合理对象状态。

@Jesus是的,它避免了“需要”,但老实说,在不需要null的时候检查它们是一个很好的实践:)是的,我宁愿传递空字符串来避免这个问题,但这只是我,在某些情况下,防御编程通常是坏代码的标志,但是如果空字符串是有效的返回,那么NULL实际上是您唯一的选择。你是对的,它可能是坏代码的标志,但也可能是一个救命稻草。老实说,这取决于它的使用方式(就像我们拥有的许多工具一样)。如果您依赖防御性编程来获得正确性,而不是进行适当的异常处理,那么这是一个坏主意。另一方面,如果您能够在异常发生之前处理它,那是一件好事!就我个人而言,我宁愿有一个例外而不是一个错误代码。性能损失可以忽略不计,拥有编译时完整性的好处是值得的。从C背景来看,我可以看到为什么用错误代码来构造它,但是我会强烈考虑将异常合并而不是错误代码。只是我的想法:)@天哪,我绝对相信使用异常来确定程序流是一个糟糕的决定。例如,
while(true){try{arr[i++]=i;}catch(arrayeexception e){break;}}
非常差。如果您的代码设计为happy path抛出异常,则表明您做了错事。但我宁愿为我的。。。“悲伤之路”?然后我会为我的sad路径使用一个错误代码。但是你会在下一行得到NPE,比如你想解析字符串。所以这不是一种防守技术。它不替换空检查。示例:如果(s!=null&&!“.equals(s)){value=Integer.parseInt(s);}如果忽略了parseInt()中的null检查,那么您只是将null指针延迟到其他更难诊断的错误。这些常数。(变量)在我的项目中引起了如此可怕的错误,我认为它是一个一流的反模式。这并不是在其他地方提倡减少验证,而是为什么在左边使用常量。你完全正确,可悲的事实是,下一行中会出现另一个异常。它不替换空检查。糟糕的是,你被愚弄到不再需要空检查。即使是静态分析工具(sonarcube)也推荐这种错误的方法。sonarcube推荐这种方法??那太糟糕了!在我看来,这是最糟糕的反模式之一。它只是隐藏了错误,并将其变成了一个更难找到的错误。这是唯一一个sonarcube推荐版本,它在我的上一个软件版本中导致了一个错误。左边的contant可能会产生一些非常糟糕的副作用。抛出空指针是有原因的。