71

让我们以一个简单的对象为例Cat。我想确定“not null”cat是橙色还是灰色。

if(cat != null && cat.getColor() == "orange" || cat.getColor() == "grey") {
//do stuff
}

我相信 AND 首先出现,然后是 OR。不过我有点模糊,所以这是我的问题:

  1. 有人可以指导我完成此声明,以便我确定我知道会发生什么吗?

  2. 另外,如果我添加括号会发生什么;这会改变操作的顺序吗?

  3. 我的操作顺序会因语言而异吗?

4

6 回答 6

68

Java 教程有一个说明运算符优先级的列表。将首先评估相等运算符,然后是&&,然后是||。括号将在其他任何内容之前进行评估,因此添加它们可以更改顺序。这通常在不同语言之间几乎相同,但仔细检查总是一个好主意。

正是您没有预料到的行为的微小变化会导致您花费一整天的时间进行调试,因此最好将括号放在适当的位置,这样您就可以确定评估的顺序是什么。

于 2010-02-15T02:08:23.140 回答
23

布尔运算顺序(我相信的所有语言):

  1. 括号
  2. 不是
  3. 或者

所以你上面的逻辑相当于:

(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey"
于 2010-02-15T02:05:41.130 回答
8

表达式基本等同于:

if ( (cat != null && cat.getColor() == "orange") || cat.getColor() == "grey") {
  ...
}

这里的优先顺序是 AND ( &&) 的优先级高于 OR ( ||)。

您还应该知道,==用于测试字符串相等性有时会在 Java 中起作用,但这不是您应该这样做的方式。你应该做:

if (cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) {
  ...
}

即使用equals()方法进行String比较,而不是==简单地引用相等。字符串的引用相等可能会产生误导。例如:

String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false
于 2010-02-15T02:06:08.107 回答
6

首先,您的 if 语句包含三个主要表达式:

  1. 猫!=空
  2. cat.getColor() == "橙色"
  3. cat.getColor() == "灰色"

第一个表达式只是检查 cat 是否不为空。这是必要的,否则第二个表达式将被执行并导致NPE(null pointer excpetion). 这就是为什么在第一个和第二个表达式之间使用 && 的原因。使用 时&&,如果第一个表达式的计算结果为 false,则永远不会执行第二个表达式。最后检查猫的颜色是否为灰色。

最后请注意,您的 if 语句仍然是错误的,因为如果 cat 为 null,则仍然执行第三个表达式,因此您会得到一个空指针异常

正确的做法是:

if(cat != null && (cat.getColor() == "orange" || cat.getColor() == "grey")) { 
//do stuff 
} 

检查括号的顺序。

于 2010-02-15T02:05:56.807 回答
5

&&的,肯定是之前评估过||的。但我看到你正在做cat.getColor() == "orange"这可能会给你带来意想不到的结果。您可能想要这样做:

if(cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) {
    //do stuff
}
于 2010-02-15T03:01:24.940 回答
-4

运算顺序不是您需要的,您需要布尔代数,这包括布尔函数。最大项/最小项、格雷码、卡诺表、二极管、晶体管、逻辑门、多路复用器、比特加法器、触发器......您想要的是在计算机或虚拟机上实现布尔“逻辑”。使用“操作顺序”,您可以参考一些有关物理的内容,例如管理逻辑门(或,如果)纳秒间隔的延迟?

于 2015-06-27T04:49:00.190 回答