В Java, каков логический «порядок операций»? - PullRequest
54 голосов
/ 15 февраля 2010

Давайте рассмотрим простой пример объекта Cat. Я хочу быть уверен, что "not null" cat либо оранжевый, либо серый.

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

Я верю, что И приходит первым, потом ИЛИ. Я немного неясен, так что вот мои вопросы:

  1. Может ли кто-нибудь провести меня через это утверждение, так что я уверен, что я понимаю, что происходит?

  2. Кроме того, что произойдет, если я добавлю скобки; это меняет порядок операций?

  3. Изменится ли мой порядок операций с языка на язык?

Ответы [ 6 ]

58 голосов
/ 15 февраля 2010

В руководствах по Java есть список, иллюстрирующий приоритет оператора . Сначала будут оцениваться операторы равенства, затем &&, затем ||. Скобки будут оцениваться раньше всего, поэтому их добавление может изменить порядок. Это обычно в значительной степени одинаково от языка к языку, но это всегда хорошая идея, чтобы перепроверить.

Небольшие изменения в поведении, которые вы не ожидаете, могут привести к тому, что вы потратите целый день на отладку, поэтому рекомендуется установить круглые скобки, чтобы вы были уверены в том, какой будет порядок оценки.

16 голосов
/ 15 февраля 2010

Логический порядок операций (на всех языках, которые я считаю):

  1. * 1004 круглые скобки *
  2. НЕ
  3. И
  4. OR

Так что ваша логика выше эквивалентна:

(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey"
8 голосов
/ 15 февраля 2010

Выражение в основном идентично:

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
4 голосов
/ 15 февраля 2010

Да && определенно оценивается до ||.Но я вижу, что вы делаете cat.getColor() == "orange", что может дать вам неожиданный результат.Вы можете захотеть этого вместо:

if(cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) {
    //do stuff
}
4 голосов
/ 15 февраля 2010

Во-первых, ваш оператор if содержит три основных выражения:

  1. кошка! = Ноль
  2. cat.getColor () == "оранжевый"
  3. cat.getColor () == "серый"

Первое выражение просто проверяет, не является ли cat нулевым. Это необходимо, иначе второе выражение будет выполнено и приведет к NPE(null pointer excpetion). Вот почему использование && между первым и вторым выражением. Когда вы используете &&, если первое выражение оценивается как ложное, второе выражение никогда не выполняется. Наконец вы проверяете, серый ли цвет кошки.

Наконец, обратите внимание, что ваше утверждение if все еще неправильно , потому что если кошка ноль, третье выражение все еще выполнено и, следовательно, вы получите ноль исключение указателя .

Правильный способ сделать это:

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

Проверьте порядок скобок.

0 голосов
/ 27 июня 2015

Порядок операций - это не то, что вам нужно, вам нужна булева алгебра, сюда входят булевы функции. Maxterms / minterms, код Грея, таблицы Карно, диоды, транзисторы, логические вентили, мультиплексоры, битрейдеры, шлепки ... Вам нужно реализовать логическую «логику» на компьютерах или виртуальных машинах. С «порядком операций» вы можете ссылаться на физику, например, на управление задержками на логических элементах (или, если), на наносекундах?

...