В Java, каков булев “порядок операций”?

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

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

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

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

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

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

58
задан Bill the Lizard 11 January 2014 в 15:44
поделиться

5 ответов

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

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

60
ответ дан 24 November 2019 в 18:58
поделиться

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

  1. parens
  2. НЕ
  3. И
  4. ИЛИ

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

(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey"
20
ответ дан 24 November 2019 в 18:58
поделиться

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

if(cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) {
    //do stuff
}
4
ответ дан 24 November 2019 в 18:58
поделиться

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

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
8
ответ дан 24 November 2019 в 18:58
поделиться

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

  1. cat! = Null
  2. cat.getColor () == "orange"
  3. cat.getColor () == "серый"

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

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

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

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

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

4
ответ дан 24 November 2019 в 18:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: