2010-02-15 3 views
46

Давайте рассмотрим простой пример объекта Cat. Я хочу быть уверенным, что «не null» cat либо оранжевый, либо серый.В Java, каков булевский «порядок операций»?

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

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

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

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

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

+11

Если вы вообще нечеткие, добавьте круглые скобки, чтобы это было очевидно. –

+34

Даже если это не смущает вас, добавьте круглые скобки, чтобы другие люди могли это понять. –

+2

Из википедии по логической логике: в таких случаях [двусмысленности] круглые скобки могут использоваться для уточнения порядка операций. Как всегда, сначала выполняются операции внутри самой внутренней пары, а затем следующая пара и т. Д. До тех пор, пока все операции в круглых скобках не будут завершены. Затем выполняются любые операции вне круглых скобок. – Stephano

ответ

54

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

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

+1

@VinceEmigh Операнды не должны оцениваться в том же порядке, что и приоритет оператора. Даже если вы добавляете круглые скобки, программа все равно может видеть, что 'if (true || (true && s.equals (" ")))' всегда будет 'true', поэтому не нужно оценивать' s.equals ("") 'вообще. –

+0

Мой плохой, я просто понял, что сильно ошибаюсь. Я не думал о приоритете правильно. Я думал об оценке (которая сначала оценивается), так как оператор «владеет» булевыми –

14

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

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

Таким образом, ваша логика выше эквивалентна до:

(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey" 
4

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

  1. кот = NULL
  2. cat.getColor() == "оранжевый"
  3. cat.getColor() == «серые! "

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

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

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

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

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

8

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

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

Порядок старшинства здесь является то, что И (&&) имеет более высокий приоритет, чем или (||).

Вы также должны знать, что с помощью == для проверки равенства строк будет иногда работать на 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 
+0

Я думаю, что в первом примере у вас отсутствует пар, или я просто слишком устал. –

+0

@Robert: они были испорчены. Исправлено, спасибо. – cletus

3

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

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

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

Смежные вопросы