Ответы:
Это побитовые операторы И и ИЛИ.
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 ), касающийся различного поведения оператора в зависимости от его входных данных.
Действительно, когда оба входа являются логическими, операторы считаются логическими логическими операторами и ведут себя аналогично операторам Conditional-And ( &&
) и Conditional-Or ( ||
), за исключением того факта, что они не замыкаются, поэтому следующее безопасно :
if((a != null) && (a.something == 3)){
}
Это не:
if((a != null) & (a.something == 3)){
}
«Короткое замыкание» означает, что оператор не обязательно проверяет все условия. В приведенных выше примерах, &&
рассмотрим второе условие только тогда , когда a
нет null
( в противном случае весь оператор вернет ложь, и было бы спорно рассмотреть следующие условия в любом случае), поэтому утверждение a.something
не вызывает исключение, или считается «безопасным . "
&
Оператор всегда рассматривает все условия в предложении, так и в приведенных выше примерах, a.something
может быть оценен , когда a
на самом деле null
значение, вызывая исключение.
Я думаю, вы говорите о логическом значении обоих операторов, вот вам таблица-резюме:
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
Оценка короткого замыкания , минимальная оценка или оценка Маккарти (после Джона Маккарти) - это семантика некоторых булевых операторов в некоторых языках программирования, в которых второй аргумент выполняется или оценивается только в том случае, если первого аргумента недостаточно для определения значения выражение: когда первый аргумент функции И оценивается как ложь, общее значение должно быть ложным; и когда первый аргумент функции ИЛИ оценивается как истина, общее значение должно быть истиной.
Not Safe означает, что оператор всегда проверяет каждое условие в предложении, поэтому в приведенных выше примерах 1 / x может быть оценено, когда x фактически равен 0, что вызывает исключение.
Я знаю, что здесь много ответов, но все они кажутся немного запутанными. Итак, проведя небольшое исследование из руководства по изучению Java oracle, я придумал три разных сценария, когда использовать && или &. Три сценария логическое И , побитовое И и логическое И .
Логическое И:
логическое И (также известное как Условное И) использует оператор && . Это сокращенное значение: если левый операнд ложен, то правый операнд не будет оцениваться.
Пример:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
В приведенном выше примере значение, выводимое на консоль x, будет равно 0, потому что первый операнд в операторе if имеет значение false, следовательно, java не нужно вычислять (1 == ++ x), поэтому x не будет вычисляться.
Поразрядное И: Поразрядное И использует оператор & . Он используется для выполнения побитовой операции над значением. Намного легче увидеть, что происходит, взглянув на операции с двоичными числами, например:
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.
Логическое И: теперь логический оператор И ведет себя одинаково и по-разному как с побитовым И, так и с логическим И. Мне нравится думать об этом как о преформинге побитового И между двумя логическими значениями (или битами), поэтому он использует оператор & . Логические значения также могут быть результатом логического выражения.
Он возвращает либо истинное, либо ложное значение, во многом аналогично логическому И, но в отличие от логического И оно не замыкается. Причина в том, что для выполнения побитового И он должен знать значения левого и правого операндов. Вот пример:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Теперь, когда этот оператор if запущен, выражение (1 == ++ x) будет выполнено, даже если левый операнд ложен. Следовательно, значение x будет равно 1, потому что оно увеличилось.
Это также относится к логическому ИЛИ (||), поразрядному ИЛИ (|) и логическому ИЛИ (|). Надеюсь, это устраняет некоторую путаницу.
to preform that bitwise AND, it must know the value of both left and right operands
Мне это не кажется правильным. Для выполнения BITWISE AND
вам не нужно знать правый операнд, чтобы иметь возможность вычислить результат, если левый операнд FALSE
. То, что вы объясняете, правильно, но аргументация, которую вы излагаете, не кажется таковой, по крайней мере, мне ..
Операторы && и || являются короткозамкнутыми, что означает, что они не будут оценивать свое правое выражение, если значение левого выражения достаточно для определения результата.
& и | обеспечивают тот же результат, что и && и || операторы. Разница в том, что они всегда оценивают обе стороны выражения, где как && и || прекратите оценивать, достаточно ли первого условия для определения результата.
&&
он оценивает оба результата, а ||
возвращает только если первое условие истинно.
( 2 & 4 )
оценивает до false
, тогда как ( 2 && 4 )
оценивает до true
. Как именно такой результат?
2 & 4
приводит к целому числу, а не к логическому (в данном случае ноль). 2 && 4
не будет компилироваться, && принимает только логические значения. Java не позволяет смешивать логические значения и целые числа: ноль - нет false
, false
не равен нулю ...
&&
он оценивает только второй операнд, если первый операнд true
.
В Java одиночные операторы &, |, ^,! зависят от операндов. Если оба операнда - целые числа, выполняется побитовая операция. Если оба являются логическими, выполняется «логическая» операция.
Если оба операнда не совпадают, возникает ошибка времени компиляции.
Двойные операторы &&, || ведут себя так же, как их одиночные аналоги, но оба операнда должны быть условными выражениями, например:
if ((a <0) && (b <0)) {...} или аналогично, if ((a <0) || (b <0)) {...}
источник: язык программирования Java 4-е изд
&
и |
являются поразрядными операторами для целых типов (например int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
и ||
работать только с логическими значениями (и коротким замыканием, как уже говорили другие ответы).
&
и |
также являются логическими операторами для логических типов.
Может быть полезно знать, что побитовые операторы AND и побитовые OR всегда вычисляются до использования в одном выражении условного AND и условного OR.
if ( (1>2) && (2>1) | true) // false!
&&; || логические операторы .... короткое замыкание
&; | логические логические операторы .... Без короткого замыкания
Переходим к различиям в исполнении по выражениям. Побитовые операторы оценивают обе стороны независимо от результата левой части. Но в случае оценки выражений с помощью логических операторов оценка правого выражения зависит от левого условия.
Например:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Это напечатает i = 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);
Но это напечатает i = 26; j = 26,
Если вычисляется выражение, включающее логический оператор &, оцениваются оба операнда. Затем к операнду применяется оператор &.
Когда вычисляется выражение, включающее оператор &&, вычисляется первый операнд. Если первый операнд оценивается как ложь, оценка второго операнда пропускается.
Если первый операнд возвращает значение true, тогда оценивается второй операнд. Если второй операнд возвращает значение true, тогда к первому и второму операндам применяется оператор &&.
Аналогично для | и ||.
В то время как основное отличие состоит в том , что &
используется для битовых операций в основном на long
, int
или byte
где он может быть использован для вида маски, результаты могут отличаться , даже если использовать его вместо логического &&
.
Разница более заметна в некоторых сценариях:
Первый пункт довольно прост, он не вызывает ошибок, но требует больше времени. Если у вас есть несколько разных проверок в одном условном выражении, поместите те, которые дешевле или с большей вероятностью не пройдут, слева.
Для второго пункта см. Этот пример:
if ((a != null) & (a.isEmpty()))
Это не работает null
, поскольку оценка второго выражения дает NullPointerException
. Логический оператор &&
ленив, если левый операнд ложен, результат будет ложным независимо от того, какой правый операнд.
Пример для третьего пункта - допустим, у нас есть приложение, которое использует БД без каких-либо триггеров или каскадов. Прежде чем мы удалим объект Building, мы должны изменить здание объекта Department на другое. Предположим также, что статус операции возвращается как логическое значение (истина = успех). Затем:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Это оценивает оба выражения и, таким образом, выполняет удаление здания, даже если обновление отдела по какой-либо причине не удалось. С &&
, он работает по назначению и останавливается после первого сбоя.
Что касается a || b
, это эквивалентно !(!a && !b)
, он останавливается, если a
это правда, никаких дополнительных объяснений не требуется.