Влияние побитового оператора на логическое значение в Java - PullRequest
102 голосов
/ 12 ноября 2009

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

Однако в случае логических значений логическое значение может содержать только два значения. 1 = правда или 0 = ложь. Но размер логического значения не определен. Он может быть размером с байт или чуть меньше.

Так, каково влияние использования побитового оператора на логическое значение? По сути, JVM переводит его в обычный логический оператор и продолжает? Он рассматривает логическое значение как однобитную сущность для цели операции? Или результат не определен вместе с размером логического значения?

Ответы [ 4 ]

107 голосов
/ 12 ноября 2009

Операторы &, ^ и | являются побитовыми операторами, когда операнды являются примитивными целочисленными типами. Они являются логическими операторами, когда операнды булевы, и их поведение в последнем случае определено. Подробнее см. Раздел 15.22.2 Спецификации языка Java .

78 голосов
/ 12 ноября 2009

Использование побитового оператора может обойти короткое замыкание:

boolean b = booleanExpression1() && booleanExpression2();
boolean b = booleanExpression1() & booleanExpression2();

Если booleanExpression1() равно false, то
booleanExpression2() не оценивается в первом случае, а
booleanExpression2() (и любые побочные эффекты, которые он может иметь) оценивается во втором случае

18 голосов
/ 22 августа 2013

Помимо того, что описано в других ответах, стоит отметить, что && и || имеют приоритет от & и |.

Извлечение из таблицы приоритетов (с наивысшим приоритетом вверху).

bitwise AND                 &
bitwise exclusive OR        ^
bitwise inclusive OR        |
logical AND                 &&
logical OR                  ||

Что это значит для вас?

Абсолютно ничего, пока вы придерживаетесь только & и | или только && и ||.

Но, поскольку | имеет более высокий приоритет, чем && (в отличие от ||, который имеет более низкий приоритет), свободное их смешивание может привести к неожиданному поведению.

То есть a && b | c && d совпадает с a && (b | c) && d,
в отличие от a && b || c && d, который будет (a && b) || (c && d).

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

a | b | c | d | (b|c) | (a&&b) | (c&&d) | a && (b|c) && d | (a&&b) || (c&&d)
F | T | T | T |   T   |   F    |    T   |         F       |        T
                                                  ^                ^
                                                  |- not the same -|

Если вы хотите, чтобы OR имел более высокий приоритет, чем AND, вы могли бы использовать | и && вместе, но это не рекомендуется.

Но вам действительно следует заключать их в квадратные скобки, чтобы уточнить приоритет при использовании разных символов, т. Е. (a && b) || c (скобки, чтобы уточнить приоритет), a && b && c (без скобок).

2 голосов
/ 12 ноября 2009

Даже если это сработает, вы не должны этого делать. Спецификации языка определяют побитовые операторы, только когда оба операнда имеют примитивные целочисленные типы или оба имеют логический тип. Я бы сказал, что для любого другого случая результаты не определены:

http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5228

...