Java排序或比较

Java排序或比较,java,nullpointerexception,Java,Nullpointerexception,当参数为null时,以下代码段是否抛出NPE public void doSomething(String string) { if (string.trim().equals("") || string==null) { [...] } } 我在其他人的代码中发现了这一点(其他人应该比我更有经验)。由于我在这段代码中遇到了一些困难,我想问一下,比较是否应该反转,或者Java编译器是否足够聪明,可以交换操作数。我对这段代码没有直接的控制权,也不会因为有很多catch块而

当参数为null时,以下代码段是否抛出NPE

public void doSomething(String string) {
    if (string.trim().equals("") || string==null) {
    [...]
    }
}
我在其他人的代码中发现了这一点(其他人应该比我更有经验)。由于我在这段代码中遇到了一些困难,我想问一下,比较是否应该反转,或者Java编译器是否足够聪明,可以交换操作数。我对这段代码没有直接的控制权,也不会因为有很多catch块而引发NPE


谢谢你

是的,我觉得这很狡猾。几乎可以肯定的是,情况恰恰相反。Java逻辑运算符(如C和C++中的逻辑运算符)有一个“短路”功能,即首先计算左手操作数,然后仅在需要时计算右手操作数


[注意:难道你就不能试着运行它来确定它是否引发异常吗?]

是的。当
string
null
时,该代码片段将抛出
NullPointerException
。建议将其更改为以下内容:

public void doSomething(String string) {
    if (string==null || string.trim().equals("")) {
        // ...
    }
}

优先级相等的二进制运算符总是从左到右求值,除了赋值(在我能想到的几乎每种语言中)这在这种情况下都很重要,因为
|
是一个快捷运算符。如果结果为know,即第一个表达式为true,则不会计算第二个表达式。因此,使用
|
&&
检查null的正确方法如下所示

if(text == null || text.method())


顺序是这样的,因为我们用英语从左到右(从上到下)阅读。c、 在日语中,你从上到下再从右到左阅读。

是的,每个合理的IDE都会抱怨这段代码,因为右半部分永远无法计算

 if (string.trim().equals("") || string==null) {


如果字符串为null,则左侧部分抛出一个NPE,因此右侧部分永远不会被求值,它将抛出一个
NullPointerException
,因为如果
string
为null,并且您尝试修剪
null
,它将抛出异常。在尝试
trim()之前,请尝试进行空检查。

如果(!“”.equals(someString))可以避免显式空检查,这不是优先级/关联性问题。在C/C++/Java(以及其他一些语言)中,逻辑运算符有一个“短路”功能。对我来说,重要的问题是左表达式的求值先于右表达式。如果先计算右操作数,则OP的代码将使用快捷方式。实际上,短路意味着当第一个操作数足够时,第二个操作数不被计算。这对于避免拆分空检查和模式检查非常重要,因为如果空检查通过,则不会计算另一个操作数,也不会执行NPEshort循环,这仅意味着在结果已知时不会计算所有子表达式。在逻辑编程语言中,任何已知的子表达式都可能意味着不计算其他表达式。@彼得:是的,但在Java(和C等)中,标准中有一点规定,总是计算左手操作数,只有在必要时才计算右手操作数。这是这里的关键点…右半部分可以评估。它永远不会被计算为
true
@atrys我的意思是
如果(字符串为null){左边的部分抛出一个NPE,所以右边的部分永远不会被计算}
:-)@atrys:不管右表达式的值是多少,如果我得到NPE,就不需要再计算任何东西了,这是…:)中的一个痛苦。)整个答案似乎不正确。我想不出我使用过的任何Java IDE会抱怨这一点,仅仅因为变量-may-为null,因此-may-抛出一个NullPointerException,并且-may-意味着无法计算右侧。如果你仔细想想,这样做是完全荒谬的。Eclipse在null和notnull两种情况下都不会打印任何警告。它只会抱怨未初始化的变量,而不是空变量。这和它的行为不一样(trim在哪里?),也不是问题的答案…@Oli Charlesworth,@Asaph String包含空格字符在所有情况下对我来说都不是空的。我无法在我刚才看到的代码中调试。想想看,你甚至得到了更多的rep:)@djechelon:你可以简单地复制并粘贴这段代码到一个小测试程序中。。。!请参见-
仅当其左侧操作数的值为false时才计算其右侧操作数
,我们如何组合使用它们(
&&
|
)?有执行令吗?还是仍然是从左到右的评估?你为什么不自己试试呢?5行代码,你知道答案。参数名为str,变量名为string。这是正确的吗?@walkingTarget:在@Martijn Courtaux更正了我的答案后,我刚刚更正了这个问题。我可以随意将参数名称更改为
字符串
:D@Martijn柯托:谢谢。我没有发现参数变量名与
if
块中的变量名不同。我刚从问题中删去/粘贴了它。看起来这个问题也错了,但我刚刚纠正了。
 if (string.trim().equals("") || string==null) {