Відповіді:
Це оператори побітового AND і бітового АБО.
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 ) щодо різних поведінок оператора на основі його входів.
Дійсно, коли обидва входи булеві, оператори вважаються логічними операторами Loolean і поводяться аналогічно операторам 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
Оцінка короткого замикання , мінімальна оцінка або оцінка Маккарті (після Джона Маккарті) - це семантика деяких булевих операторів у деяких мовах програмування, в яких другий аргумент виконується або оцінюється лише в тому випадку, якщо першого аргументу недостатньо для визначення значення вираз: коли перший аргумент функції AND оцінюється як false, загальне значення повинно бути помилковим; і коли перший аргумент функції АБО оцінюється як істинне, загальне значення повинно бути істинним.
Не безпечно означає, що оператор завжди вивчає кожну умову в пункті, тому в наведених вище прикладах 1 / x може бути оцінена, коли значення x є, по суті, значенням 0, викликаючи виняток.
Я знаю, що тут багато відповідей, але всі вони здаються дещо заплутаними. Отож, провівши деякі дослідження з навчального посібника Java oracle, я придумав три різні сценарії використання && або &. Три сценарії є логічним 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 не обчислюється.
Побітові І: Побітові І використовує оператор & . Він використовується для попередньої попередньої операції зі значенням. Набагато простіше зрозуміти, що відбувається, переглянувши операцію на двійкових числах, наприклад:
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.
Булевий І: Тепер оператор булевого І поводиться так само і по-різному, як по бітовому І та логічному І. Мені подобається думати про це як попереднє формування бітового І між двома булевими значеннями (або бітами), тому він використовує & operator. Булеві значення також можуть бути результатом логічного виразу.
Він повертає або істинне, або хибне значення, подібно до логічного AND, але на відміну від логічного AND не є короткозамкненим. Причина полягає в тому, що для того, щоб виконати цю побітну операцію AND, вона повинна знати значення як лівого, так і правого операндів. Ось колишній:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Тепер, коли це запускається, вираз (1 == ++ x) буде виконаний, навіть якщо лівий операнд хибний. Значить, значення, надруковане для x, буде дорівнює 1, оскільки воно збільшується.
Це також стосується логічного АБО (||), порозрядного АБО (|) та булевого АБО (|). Сподіваюсь, це усуне певну плутанину.
to preform that bitwise AND, it must know the value of both left and right operands
Це мені не здається правильним. Для виконання a BITWISE AND
вам не потрібно знати правий операнд, щоб мати можливість з'ясувати результат, якщо лівий операнд FALSE
. Те, що ви пояснюєте, є правильним, але міркування, які ви заявляєте, не здаються мені такими, щонайменше ..
Оператори && та || вони мають коротке замикання, тобто вони не оцінюватимуть правий вираз, якщо значення лівого виразу достатньо для визначення результату.
& і | забезпечують такий же результат, як && та || операторів. Різниця полягає в тому, що вони завжди оцінюють обидві сторони виразу де як && і || припиніть оцінювати, чи вистачає першої умови, щоб визначити результат.
&&
він оцінює обидва результати, а ||
повертається лише у тому випадку, якщо перша умова є вірною.
( 2 & 4 )
оцінює до false
, тоді як ( 2 && 4 )
оцінює до true
. Як саме такий результат?
2 & 4
призводить до цілого числа, а не булевого (нуль у цьому випадку). 2 && 4
не компілюватиметься, && приймає лише булеві. Java не дозволяє змішувати булеві і ints: нуль не false
, false
не нуль ...
&&
він оцінює другий операнд лише у тому випадку, коли є перший операнд true
.
У Java єдині оператори &, |, ^,! залежать від операндів. Якщо обидва операнди є ints, то виконується побітова операція. Якщо обидва булеві, виконується "логічна" операція.
Якщо невідповідність обох операндів, викидається помилка часу компіляції.
Подвійні оператори &&, || поводяться аналогічно своїм одиночним аналогам, але обидва операнди повинні бути умовними виразами, наприклад:
якщо ((a <0) && (b <0)) {...} або аналогічно, якщо ((a <0) || (b <0)) {...}
джерело: янг програмування янг 4-е вид
&
і |
є побітними операторами на цілісні типи (наприклад int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
і ||
працюють лише на булевих (і коротке замикання, як уже говорили інші відповіді).
&
а |
також булеві оператори для булевих типів.
Можливо, може бути корисним знати, що побітові оператори AND і побітові ІЛО завжди оцінюються перед умовними AND і умовними АБО, що використовуються в одному виразі.
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
, оскільки оцінка другого виразу виробляє a NullPointerException
. Логічний оператор &&
лінивий, якщо лівий операнд хибний, результат помилковий, незалежно від того, який правий операнд.
Приклад третього моменту - скажімо, у нас є додаток, який використовує БД без жодних тригерів чи каскадів. Перш ніж видалити об'єкт Building, ми повинні змінити будівлю об'єкта Department на іншу. Скажімо також, що стан операції повертається як булева (true = успіх). Тоді:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Це оцінює обидва вирази і, таким чином, виконує видалення будівлі, навіть якщо оновлення відділу з якоїсь причини не вдалося. З&&
, він працює за призначенням і зупиняється після першої відмови.
Щодо того a || b
, він еквівалентний !(!a && !b)
, він припиняється, якщо a
це правда, більше пояснень не потрібно.