В Java, что такое логический "порядок операций"?

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

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

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

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

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

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

6 ответов


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

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


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

  1. parens
  2. не
  3. и
  4. или

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

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

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

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

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

вы также должны знать, что с помощью == для проверки на равенство строк будет иногда работает в Java, но это не так. Вы должны сделать:

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

ie использует equals() методы String сравнение, а не == который просто ссылается на равенство. Ссылочное равенство для строк может вводить в заблуждение. Например:

String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false

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

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

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

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

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

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

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


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

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

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