3

我在编写 if 语句时遇到问题,如下所示:

public void foo(List<String> list)
{
     if(list == null || list.isEmpty()){
        // something
     }

     // else
}

这是困扰我的问题:如果列表为空 list.IsEmpty() 将失败(抛出异常,我在空对象上调用方法),因为列表为空。但是,由于我在做 || (或)如果 list 为 null(这是真的),它将执行第二个块。这会抛出异常。

这个对吗?在英语中,如果 list if null 或 empty 是有意义的。这是这种情况吗?

&& 呢?还是短路?

谢谢。

4

4 回答 4

28

这是困扰我的问题:如果列表为空 list.IsEmpty() 将失败(抛出异常,我在空对象上调用方法),因为列表为空。

不,不会的。C# 和 Java 中的||运算符都是短路的。如果第一个操作数是true,则不会计算第二个操作数。

有关详细信息,请参阅Java 语言规范的第 15.24节和 C# 4 规范的第 7.12 节。

运算符类似,但这次&&如果第一个操作数是 ,它不会计算第二个操作数false。所以可以这样写:

if (list != null && list.size() > 0)

作为相反的条件。

于 2012-11-05T19:28:38.307 回答
6

和运算符||进行&&短路评估。一旦知道结果,它就会停止评估操作数。

这使得在空检查后使用值成为可能。如果计算第二个操作数,您就知道变量的状态。&&与运算符相比,它更常与运算||符一起使用:

if (x != null && x.something == 42) ...

|and&运算符不进行短路求值,因此保证对两个操作数进行求值。

如果您在条件下执行某些操作,这可能会很有用,并且您需要完成这两件事:

int x, y;
if ((x = GetValue()) != 0 & (y = GetValue()) != 0) {
  // use x
  // use y
}

但是,条件有副作用通常是代码异味,所以这样的代码并不经常使用。

于 2012-11-05T19:30:52.613 回答
2

一般来说,机器会先判断最左边的条件,如果可以的话,再对第二个条件进行快捷方式。

一个好的经验法则是,如果可以通过最左边的某个值完全确定真相(在您的情况下,如果list==null评估为true),那么它将忽略右边的部分。

于 2012-11-05T19:29:25.123 回答
2

这是困扰我的问题:如果 list 为空 list.IsEmpty() 将失败

答案是否定的

当使用||ieOR运算符时,仅在第一个条件失败时才评估第二个条件。当第一个条件为真时,不评估第二个条件。其称为Short Circuit行为。

这是因为:

  true || any value is always result into true

&&(AND) 相同,但在相反的条件下,即如果第一个条件失败,则第二个条件不评估为:

   false && any value is always going to be false.

希望这可以帮助您理解这种行为。

于 2012-11-05T19:29:25.343 回答