Java boolean | = operator
Недавно я увидел код, используя это:
boolean val = something();
val |= somethingElse();
Интересная часть - это оператор | = (двоичный тип), выполненный по булевскому примитивному типу.
Меня удивило, что | = существует для boolean, как если бы это был целочисленный тип, и искал спецификацию Java для этого оператора, но не смог найти.
Мне было бы любопытно, будет ли правильный операнд оценен, если значение left уже истинно.
Может ли кто-нибудь указать мне на эту спецификацию Java?
Ответы
Ответ 1
Из JLS:
15.26.2. Операторы присваивания соединения
Совокупное выражение выражения формы E1 op= E2
эквивалентно E1 = (T) ((E1) op (E2))
, где T
- тип E1
, за исключением того, что E1
оценивается только один раз.
15.22.2. Логические логические операторы &
, ^
и |
Если оба операнда оператора &
, ^
или |
имеют тип boolean
или boolean
, то тип побитового выражения оператора boolean
. Во всех случаях операнды подлежат распаковке (см. П. 5.1.8).
Для |
значение результата равно false, если оба значения операнда ложны; в противном случае результат верен.
Это означает, что
val |= somethingElse();
строго эквивалентно
val = val | somethingElse();
(если somethingElse()
возвращает boolean
или boolean
).
Мне было бы любопытно, будет ли правильный операнд оценен, если значение left уже истинно.
Да, это будет оценено, так как |
не имеет короткого замыкания:
15.7.2. Оценка операндов до операции
Язык программирования Java гарантирует, что каждый операнд оператора (кроме условных операторов &&
, ||
и ? :
) оказывается полностью оцененным до того, как будет выполнена любая часть самой операции.
15.24. Условный или оператор ||
Таким образом, ||
вычисляет тот же результат, что и |
в операндах boolean
или boolean
. Он отличается только тем, что выражение правого операнда оценивается условно, а не всегда.
Ответ 2
См. Http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.22.2 для определения |
, См http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.2 для Defintion из |=
. Определения - это то, что вы думаете.
Что меня удивляет, так это отсутствие оператора ||=
.
Ответ 3
Побитовые логические операторы будут иметь тот же эффект от "нормальных" логических операторов на булевых языках.
От Спецификация языка Java 15.22:
Когда оба операнда a &, ^ или | операторы имеют тип boolean или Boolean, тогда тип побитового выражения оператора является логическим. Во всех случаях операнды подлежат распаковке преобразования (п. 5.1.8) при необходимости.
Для &, значение результата истинно, если оба значения операнда истинны; в противном случае результат будет ложным.
Для элемента ^ значение результата истинно, если значения операнда различны; в противном случае результат будет ложным.
Для | значение результата ложно, если оба значения операнда ложны; в противном случае результат верен.
Единственное реальное отличие заключается в том, что побитовые операторы не могут использоваться для оценки короткого замыкания.
Например, этот код будет бросать NullPointerException
:
Boolean b1 = new Boolean(true);
Boolean b2 = null;
if (b1 || b2) {
//no null pointer here;
}
if (b1 | b2) {
//null pointer here;
}
Ответ 4
>>I'd be curious if right operand is evaluated if left value already is true.
Побитовые операторы (например, |
, &
,..) оценивают обе стороны до завершения.
Логические операторы (например, &&
, ||
,..) могут пропустить оценку второй части в некоторых случаях. Это называется short-circuit
.
Ответ 5
Он не является бинарным, а логическим выражением "OR" означает
val |= {something else}
совпадает с булевым выражением:
val == val or {something else}
который является включительным или (регулярным или используется в выражениях математики и информатики)
В некоторых языках программирования или отмечен двумя символами || знаки и в некоторых на один | одним из них является SQL и все языки баз данных, которые я знаю о DTD JSON и т.д.