Я знаю правила для &&
и ||
, но что такое &
и |
? Пожалуйста, объясните это мне на примере.
Различия в булевых операторах: & vs && и | vs ||
Ответ 1
Это операторы побитового И и побитового ИЛИ.
int a = 6; // 110
int b = 4; // 100
// Bitwise AND
int c = a & b;
// 110
// & 100
// -----
// 100
// Bitwise OR
int d = a | b;
// 110
// | 100
// -----
// 110
System.out.println(c); // 4
System.out.println(d); // 6
Спасибо Карлосу за то, что он указал на соответствующий раздел в спецификации языка Java (15.22.1, 15.22.2), касающийся различного поведения оператора на основе его входных данных.
Действительно, когда оба входа являются булевыми, операторы считаются булевыми логическими операторами и ведут себя подобно операторам условного и (&&
) и условного или (||
), за исключением того факта, что они не закорачивают так что пока следующее безопасно:
if((a != null) && (a.something == 3)){
}
Это не так:
if((a != null) & (a.something == 3)){
}
"Короткое замыкание" означает, что оператор не обязательно проверяет все условия. В приведенных выше примерах &&
будет проверять второе условие, только когда a
не является null
(в противном случае весь оператор вернет false, и в любом случае было бы спорным исследовать следующие условия), поэтому утверждение a.something
не вызывает исключение или считается "безопасным".
Оператор &
всегда проверяет каждое условие в предложении, поэтому в приведенных выше примерах a.something
может оцениваться, когда a
фактически является значением null
, вызывая исключение.
Ответ 2
Я думаю, что вы говорите о логическом значении обоих операторов, здесь у вас есть таблица-резюме:
boolean a, b;
Operation Meaning Note
--------- ------- ----
a && b logical AND short-circuiting
a || b logical OR short-circuiting
a & b boolean logical AND not short-circuiting
a | b boolean logical OR not short-circuiting
a ^ b boolean logical exclusive OR
!a logical NOT
short-circuiting (x != 0) && (1/x > 1) SAFE
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE
Оценка короткого замыкания, минимальная оценка или оценка Маккарти (после Джона Маккарти) - это семантика некоторых логических операторов в некоторых языках программирования, в которых второй аргумент выполняется или оценивается, только если первого аргумента недостаточно определить значение выражения: когда первый аргумент функции AND оценивается как ложное, общее значение должно быть ложным; и когда первый аргумент функции OR оценивается как true, общее значение должно быть истинным.
Небезопасно означает, что оператор всегда проверяет каждое условие в предложении, поэтому в приведенных выше примерах 1/x может оцениваться, когда значение x на самом деле равно 0, вызывая исключение.
Ответ 3
Здесь я знаю много ответов, но все они кажутся немного запутанными. Поэтому, после некоторых исследований из руководства по изучению оракула Java, я придумал три разных сценария: когда использовать && или &. Три сценария логические AND, побитовые AND и логические AND.
Логическое И:
Логический И (ака условный И) использует оператор &&. Это короткое замыкание: если левый операнд ложный, то правый операнд не будет оцениваться.
Пример:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
В приведенном выше примере значение, напечатанное на консоли x, будет равно 0, потому что первый операнд в выражении if является ложным, поэтому java не нужно вычислять (1 == ++ x), поэтому x не будет вычислено.
Побитовое И: Побитовое И использует оператор &. Он использовался для предварительной побитовой операции над значением. Намного легче понять, что происходит, если посмотреть на операцию над двоичными числами ex:
int a = 5; // 5 in binary is 0101
int b = 12; // 12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4
Как вы можете видеть в примере, когда бинарные представления чисел 5 и 12 выстроились в линию, тогда побитовое И предварительно сформированное будет производить только двоичное число, где одна и та же цифра в обоих числах имеет 1. Следовательно, 0101 и 1100 == 0100. Что в десятичной форме равно 5 и 12 == 4.
Логическое И: Теперь логический оператор ИО ведет себя аналогично и по-разному как поразрядным И, так и логическим И. Мне нравится думать об этом как о предварительном формировании побитового И между двумя логическими значениями (или битами), поэтому он использует оператор &. Булевские значения также могут быть результатом логического выражения.
Он возвращает либо истинное, либо ложное значение, подобно логическому И, но в отличие от логического И он не закорочен. Причиной является то, что для того, чтобы он преформировал побитовое И, он должен знать значение как левого, так и правого операндов. Здесь ex:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Теперь, когда этот оператор if запущен, будет выполняться выражение (1 == ++ x), хотя левый операнд является ложным. Следовательно, значение, напечатанное для x, будет равно 1, потому что оно увеличилось.
Это также относится к логическому OR (||), побитому OR (|) и логическому OR (|) Надеюсь, что это немного смущает.
Ответ 4
Операторы && и || являются короткозамкнутыми, то есть они не будут оценивать их правое выражение, если значение левого выражения достаточно для определения результата.
Ответ 5
& и | обеспечивают тот же результат, что и && и || операторы. Разница в том, что они всегда оценивают обе стороны выражения, где as && и || прекратите оценивать, достаточно ли первого условия для определения результата.
Ответ 6
В Java одиночные операторы &, |, ^,! зависят от операндов. Если оба операнда являются int, то выполняется побитовая операция. Если оба являются логическими, выполняется "логическая" операция.
Если оба операнда не совпадают, возникает ошибка времени компиляции.
Двойные операторы &, || ведут себя аналогично их одиночным аналогам, но оба операнда должны быть условными выражениями, например:
если ((a < 0) && (b < 0)) {...} или аналогично, если ((a < 0) || (b < 0)) {...}
source: java programming lang 4th ed
Ответ 7
&
и |
являются побитовыми операторами на интегральных типах (например, int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
и ||
работают только с булевыми (и короткое замыкание, как уже сказали другие ответы).
Ответ 8
Может быть, полезно знать, что побитовые И и побитовые операторы OR всегда оцениваются до условного И и условного ИЛИ используются в одном выражении.
if ( (1>2) && (2>1) | true) // false!
Ответ 9
& &; || являются логическими операторами.... короткое замыкание
&; | являются логическими логическими операторами.... Некороткое замыкание
Переход к различиям в исполнении выражений. Побитовые операторы оценивают обе стороны независимо от результата левой стороны. Но в случае оценки выражений с логическими операторами оценка выражения правой руки зависит от левого условия.
Пример:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Это напечатает я = 26; j = 25. Поскольку первое условие ложно, условие правой руки обходит, так как результат в любом случае неверен независимо от состояния правой стороны. (короткое замыкание)
int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Но это напечатает я = 26; J = 26,
Ответ 10
Если вычисляется выражение с использованием логического оператора &, оба операнда оцениваются. Затем оператор и применяется к операнду.
Когда вычисляется выражение с участием оператора &, вычисляется первый операнд. Если первый операнд оценивает значение false, оценка второго операнда пропускается.
Если первый операнд возвращает значение true, тогда вычисляется второй операнд. Если второй операнд возвращает значение true, то && оператор затем применяется к первому и второму операндам.
Похожие для | и ||.
Ответ 11
В то время как основное отличие состоит в том, что &
используется для побитовых операций в основном на long
, int
или byte
, где его можно использовать для вида маски, результаты могут отличаться, даже если вы используете его вместо логического &&
.
В некоторых сценариях разница более заметна:
- Оценка некоторых выражений требует много времени.
- Оценка одного из выражений может быть выполнена только в том случае, если предыдущий был истинным
- Выражения имеют некоторый побочный эффект (предполагаемый или нет)
Первая точка довольно проста, она не вызывает ошибок, но требуется больше времени. Если в одном условном выражении имеется несколько разных проверок, поместите те, которые дешевле или, скорее всего, не сработают слева.
Для второй точки см. этот пример:
if ((a != null) & (a.isEmpty()))
Это не выполняется для null
, так как оценка второго выражения выражает a NullPointerException
. Логический оператор &&
ленив, если левый операнд ложный, результат будет ложным независимо от того, какой правый операнд есть.
Пример для третьего пункта - скажем, у нас есть приложение, которое использует БД без каких-либо триггеров или каскадов. Прежде чем удалить объект "Строительство", мы должны сменить объект объекта "Отдел" на другой. Пусть также говорят, что статус операции возвращается как логическое (true = success). Тогда:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Это оценивает оба выражения и, таким образом, выполняет удаление зданий, даже если обновление отдела не удалось по какой-то причине. С помощью &&
он работает по назначению и останавливается после первого отказа.
Что касается a || b
, он эквивалентен !(!a && !b)
, он останавливается, если a
истинно, больше не нужно объяснять.
Ответ 12
二进制 模拟 加法 操作, 先 加 不 进 位 得 А, 然后 算 进 位 得 В, 然后 (B << 1) +A 即 得到 两个 数 之 和.A 可以 由 两个 数 的 ^ 得到, В 可以 有 & B得到.
int plus(int num1,int num2){
if(num2==0) return num1;
return plus(num1^num2,(num1&num2)<<1);}