在字符串文字上调用equals

Kub*_*tny 23 java string comparison

我只是整理了我的代码并且有这篇文章:

String saving = getValue();
if(saving != null && saving.equals("true")){
   // do something
}
Run Code Online (Sandbox Code Playgroud)

然后我想到了另一种方法来摆脱检查null:

if("true".equals(saving)){
   // do something
}
Run Code Online (Sandbox Code Playgroud)

它确实有效,但这样是否安全?我的意思是字符串文字存储在公共池中,而字符串对象create by存储在new堆上.但是常量池中的字符串也是对象,对吧?

但即使它使代码更短,它似乎也不是正确的做法.

jak*_*son 23

这是安全的 - 正如您所见,这是一种避免空指针的好方法.

你提到了使用newfor Strings.许多java静态代码分析工具都会建议总是使用文字new String("foo");.

编辑:

如果你愿意,你甚至可以使用:

if (Boolean.valueOf(saving)) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

根据文件,传球null将返回false.

  • 出于某种原因抛出运行时异常.隐藏可能会导致更严重的问题. (4认同)

Old*_*eon 23

为了确保对这个问题有一套完全平衡的答案,我想发表一个不同的意见.

我认为这种机制是愚蠢的.

如果你有一个,null你应该尽快知道 - 隐藏它只会推迟它的发现.如果null不是例外,请将其替换为其他内容.

采用这种方法将使用所谓的防御性编程来强化您的代码,在这种情况下,您可以尽快发现错误,而不是掩盖,直到一切都崩溃.

总之 - NullPointerException是你的朋友.您应该使用它来查找代码中的错误.这是容易使用一个空的对象,如Collections.emptySet()一旦你已经确定,null也不例外.

使用Yoda技术的习惯将不可避免地隐藏你不想隐藏的错误.使用它会更早地暴露错误.对我而言,这是充分论证不使用它 - 永远.

给我 - 使用

if(saving != null && saving.equals("true")){
Run Code Online (Sandbox Code Playgroud)

意味着,其实我是想允许savingsnull,它是一个可以接受的情况-使用

if("true".equals(saving)){
Run Code Online (Sandbox Code Playgroud)

只是以一种可能成为坏习惯的方式隐藏那种刻意的选择.


Mar*_*oun 9

我不同意一些答案.有时您确实想知道您的变量是否是null.这可能表明您的代码中发生了一些不好的事情,您可能想重新考虑您的逻辑.

我不喜欢这样做if("someString".equals(myString));,因为我想知道,如果myStringnull,也许办理或者改变我的逻辑,以防止类似的情况.

想象一下,由于某些错误,您有一个被错误计算的对象数组:

myStrings = {..., ..., null, null, ...};
Run Code Online (Sandbox Code Playgroud)

然后你想对数组的对象执行一些操作,你将拥有:

if("myString".equals(myObjArray[i])) { ... } 
Run Code Online (Sandbox Code Playgroud)

你不会得到NullPointerException,你会认为你对数组中的所有对象执行了操作..而且你永远不会知道你错误地计算了它,因为你"隐藏"了异常.如果你做了:

if(myObjArray[i].equals("myString")) { ... } 
Run Code Online (Sandbox Code Playgroud)

你会得到一个NPE并且你会知道数组中有什么问题......你可能想要修复它或以另一种方式处理它.


Sim*_*iak 8

它被称为yoda条件(在比较中将变量放在一个常量之前)可以被认为是不好的做法,也许对于那些可读性较差的人(比如我).

但有时使用yoda条件会使代码更"易于理解",->您不需要在它前面添加额外的空值检查,它可以有效地区分代码块与强烈禁止null的情况.

  • +1提及术语.我不认为它被广泛认为是一种不好的做法 - 更多的是这种语言的不幸后果.当然,阅读起来有点尴尬,但你已经习惯了 - 就像你对任何编程语言的其他奇怪之处一样. (4认同)
  • 也许值得注意的是,这种做法至少可以追溯到C,它用来防止`=`vs` ==`拼写错误.C是弱类型的,所以你可以做`if(myInt = 4)`.这将`myInt`赋值为'4`然后在条件中使用它(它是真值).程序员_probably_意味着`if(myInt == 4)`,但编译器不知道.另一方面`if(4 = myInt)`失败(你不能给'4`分配一个新值),它告诉程序员他们打算输入`if(4 == myInt)`. (4认同)