Эффект побитового оператора на булевом языке в Java

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

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

Итак, каков эффект использования побитового оператора на булевом? Разве JVM существенно переводит его в обычный логический оператор и движется дальше? Обрабатывает ли он логическое значение как единичный бит для целей операции? Или результат undefined вместе с размером булевых?

Ответ 1

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

Ответ 2

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

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

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

Ответ 3

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

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

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 (без скобок).

Ответ 4

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

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