Эффект побитового оператора на булевом языке в 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