Механизм короткого замыкания логического оператора Java (&&, ||)
Когда я читал код Java-коллеги, я наткнулся на команду if/else. В этих утверждениях несколько операторов &&
и ||
сражались друг с другом без какой-либо помощи из круглых скобок. Я упростил следующие утверждения:
if (true || true && false)
return true;
else
return false;
Как вы думаете, какой результат будет? Честно говоря, я думал, что это будет false
, но кажется, что короткое замыкание не работает, как я ожидал. В этом случае результат true
. Механизм короткого замыкания, по-видимому, рассматривает все выражение как true
, когда он находит true
, за которым следует ||
.
Но в обратном выражении, каков результат?
if (false && true || true)
return true;
else
return false;
Если следовать той же логике, она должна быть ложной. первое булево значение false
, и за ним сразу следует &&
, но результат true
, еще раз. Это имеет смысл для меня, но это кажется несовместимым с нашим предыдущим экспериментом.
Итак, моя теория:
Если мы найдем true
, за которым следует ||
, тогда это true
, независимо от того, что может произойти дальше, даже если есть длинный список других логических операторов, следующих за ним. Но если мы найдем false
, за которым следует &&
, он только замыкает следующий элемент, а не весь оператор.
И вот мой вопрос:
Я прав? Мне кажется, это немного глупо. Является true
сильнее, чем false
?
Ответы
Ответ 1
Это просто потому, что
if (false && true || true)
эквивалентно (&&
имеет более высокий приоритет)
if ((false && true) || true)
который
if (false || true)
который... true
.
Примечание. В выражении true || true && false
часть true && false
называется мертвым кодом, потому что она не влияет на окончательный результат оценки, так как true || anything
всегда true
.
Стоит отметить, что существуют операторы &
и |
, которые могут быть применены к логическим значениям, они очень похожи на &&
и ||
, за исключением того, что они не являются короткозамкнутыми, что означает, что если у вас есть следующее выражение:
if (someMethod() & anotherMethod())
и someMethod
возвращает false
, anotherMethod
все равно будет достигнуто! Но if
не будет выполняться, потому что окончательный результат будет оценен как false
.
Ответ 2
&&
имеет более высокий приоритет работы над ||
, поэтому он выигрывает.
Ответ 3
В соответствии с учебниками по Java &&
имеет более высокий приоритет над ||
Итак, ваш true || true && false
будет оцениваться как true || (true && false)
И ваш false && true || true
будет оцениваться как (false && true) || true
Результат в выражении true
в обоих случаях.
Ответ 4
для &&
:
false && &... = > false
для ||
:
true ||... = > true.
И приоритет для &&
выше ||
.
Подробнее: Приоритет оператора в Java
Ответ 5
Из-за приоритета &&
на ||
, (true || true && false)
это будет оцениваться как (true || (true && false)) -> (true || (false)) -> true
См. правила приоритетов: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
Ответ 6
Я вижу, что вы пытались сделать, но перед тем, как действовать в круглых скобках, полезно иметь спецификацию языка. Я знал несколько программистов, которые дошли до того, что сохраняли важные бит, например, приоритет оператора, на своих стенах.
Вторая часть - знать, будут ли ваши изменения иметь смысл для других людей на вашем рабочем месте; если удаление скобок компрометирует значение операции для кого-то другого, работающего над кодом, тогда это может в конечном итоге быть вредным.
Оптимизатор, как правило, позаботится об этом для вас, поэтому, когда вы сомневаетесь, оставьте их там.