采访:Java Equals

39

我在面试中被问到了这个问题。以下哪种更好使用?

 MyInput.equals("Something");   

或者

"Something".equals(MyInput);

感谢


19
尽管其他人在答案中指出第二个解决方案对于"MyInput"为空的情况很强大,但我认为如果你可以确定"MyInput"是非空的话,第一个解决方案在可读性方面更好。 - Heinzi
7个回答

63

我会选择

"Something".equals(MyInput);
在这种情况下,如果 MyInput 是 null,那么它不会抛出 NullPointerException
在这里,我们可以确保要调用 equals() 的对象是 NOT NULL
如果你期望从你的代码中获得 NullPointerException 以便做出某些决策或者抛出/包装它,请选择第一种方法。
没有性能影响。

16
如果一个变量是 null 并且我并不希望它是这样,我更愿意快速失败并通过异常得到通知,而不是让它默默地失败,或者在更难以调试的情况下潜在地失败。第一种方式更易读、更自然,这是良好代码的重要组成部分。 - Kevin
7
我不相信这样的答案能获得这么多赞并被认为是正确的!这种做法非常糟糕——改变变量/常量值以避免NullPointerException是一种邀请潜在疯狂行为进入生产环境的可怕方式。如果你希望输入可能为空,则请在String比较之前进行检查。如果您从未预期它为空,则这需要在应用程序中严格执行,以便您可以调查可能导致该空值的用户故事并相应地处理它们。 - SiN
我们这里不讨论最佳实践,答案中已经提到了。 - jmj

21

要成为一个与众不同的人.... :)

如果'MyInput'为空,第一行代码可能会崩溃,但这只是程序员(通常是因为C语言遗留问题)在不想断言'MyInput'可以为空时使用的一种代码便利。

如果使用第二个选项,那么也许这行代码不会导致NullPointerException,但接下来的代码行可能会。

我认为最好了解您的变量可能存在的状态,而不是依赖某些代码结构来减轻良心负担。


虽然是的,我还在康复中...但有时候我可能会期望MyInput为空,这也没关系。它确实有用处;) - Brian Roach
你假设当myInput为null时会在后面引起NPE,因此认为null值不是有效值。但这并非没有更多信息的情况下可以做出的假设。 - jwenting
5
我曾经以一种“掩盖”式的方式来写作。但是,当我开始使用Java时,我习惯于使用null来表示空集合。NPE(空指针异常)非常普遍。在代码上下文中,null几乎没有任何意义。因此,最好避免使用null,这意味着需要进行检查。此外,在这里与之相关的是,不要试图掩盖任何错误。 - Tom Hawtin - tackline
3
如果您知道 myInput 可能为 null,那么请编写 myInput != null && myInput.equals("Something") 来告诉读者。是的,这样会更长,但更加信息丰富,因此值得。现在读者知道 myInput 可能为空(如果要修改代码,则是关键知识),并且知道您已经考虑到了它并将其纳入考虑范围。或者,如果您坚持要缩短代码,可以使用 Objects.equals(myInput, "Something") - Ole V.V.

5

那我们换个方式,把整个代码倒过来写怎么样?

喜欢把常量放在最前面的人,看到这样的代码会有什么感觉呢?

if ( 2 == i) 

在我看来,隐藏空指针异常从来不是一种优点,而是设计上的缺陷。如果您从未预料到空指针异常但出现了这种情况,那么您需要让应用程序崩溃,跟踪日志并查看为什么会发生这种情况。这可能是您完全忽略的业务案例 :)
如果您可以选择地期望一个空参数并且不想单独处理它,则可以使用类似于StringUtils.equals(...)的实用方法。
话虽如此,我从不允许我的任何团队成员使用第二种形式,因为它不一致且不可读。

3

如果MyInputnull,前者将引发NullPointerException,而后者将只返回false,因此在某些情况下可能更喜欢使用后者(或者如果您不希望MyInput为空并且想要快速失败,则可能更喜欢前者)。


1

如果你想成为一个真正的聪明人,你可以指出MyInput可能是一个特殊的String子类,它已经重写了equalshashcode方法。在这种情况下,语句的顺序非常重要。

这里有一个现实生活中的例子 - 如果你想比较带有数字的字符串,并且你想忽略前导零怎么办?例如,Lecture1将等于Lecture01


3
因为String无法被子类化,所以您需要使用不同的方法或Comparator,聪明的先生。 - Petr Janeček
@Slanec,实际上没有任何地方说MyInput是一个字符串。因此它可以是字符串的子类,也可以是其他任何类型(甚至是原始类型,在这种情况下第一种情况无法编译)。 - njzk2

-2
我会使用"something".equals(myInput);,因为变量可能为空,如果变量为空,它会简单地抛出异常。

-5
一个好的开发者总是会尽量避免NullPointerException,因此最好的答案是使用"Something".equals(myInput)

3
所以你基本上用与2011年4月被接受的答案相同的方式回答了一个一年前的问题?! - mbinette
6
一个“好的开发者”会在调用之前检查空值,或者更倾向于抛出异常,而不是让它默默地失败,可能以更不可预测的方式引入错误。而且更重要的是,第一种方法更易读,也更自然。 - Kevin
3
一个好的开发者总是会尽力避免空指针异常 - 这是你的搭讪台词吗? - Mukus
避免NullPointerException的另一种方法是在该区域周围使用try...catch(Throwable)进行包装 :) - SiN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接