Яка різниця між & і && на Java?


167

Я завжди думав, що &&оператор в Java використовується для перевірки того, чи є обидва його булеві операнди true, а &оператор використовується для операцій з бітними операціями на двох цілих типах.

Нещодавно я дізнався, що &оператор також може бути використаний для перевірки того, чи є обидва його булеві операнди true, єдиною різницею є те, що він перевіряє операнд RHS, навіть якщо операнд LHS помилковий.

Чи &оператор на Java внутрішньо перевантажений? Або за цим стоїть якась інша концепція?



Подвійний виконує ярлик, якщо це можливо.
Ніколас Гамільтон

Відповіді:


278

& <- перевіряє обидва операнди
&& <- припиняє оцінювати, якщо перший операнд оцінюється як false, оскільки результат буде хибним

(x != 0) & (1/x > 1)<- це означає оцінити, (x != 0)потім оцінити, (1/x > 1)потім зробіть &. проблема полягає в тому, що для x = 0 це призведе до виключення.

(x != 0) && (1/x > 1)<- це означає оцінити, (x != 0)і лише якщо це правда, тоді оцініть, (1/x > 1)тому якщо у вас x = 0, то це абсолютно безпечно і не викине жодного винятку, якщо (x! = 0) оцінюється як хибне, вся справа безпосередньо оцінюється як false без оцінки (1/x > 1).

Редагувати:

exprA | exprB<- це означає оцінити, exprAа потім оцінити, exprBто зробіть |.

exprA || exprB<- це означає оцінювати, exprAі лише якщо це falseпотім оцінювати exprBі робити ||.


7
Яка причина написати один & | у якщо заява? Це ніколи не буде швидше, ніж && та || Чому ми хочемо перевірити другу умову, якщо вже можемо відповісти? Чи можете ви надати, реалістичний приклад, будь ласка?
Мічу93

14
@ Michu93: Одним із прикладів може бути, якщо друга умова - це виклик функції, який має побічний ефект, який вам завжди потрібен. Оскільки, як правило, слід уникати побічних ефектів, тоді вам потрібні лише рідкісні випадки, і я не можу придумати реалістичний приклад на даний момент.
Хайнзі

54

Окрім того, що не лінивий оцінювач, оцінюючи обидва операнди, я думаю, що основні характеристики побітових операторів порівнюють кожен байт операндів, як у наступному прикладі:

int a = 4;
int b = 7;
System.out.println(a & b); // prints 4
//meaning in an 32 bit system
// 00000000 00000000 00000000 00000100
// 00000000 00000000 00000000 00000111
// ===================================
// 00000000 00000000 00000000 00000100

2
Питання стосується логічних операцій, а не розрядних операцій.
Маркіз Лорнський

21
@EJP Це допомагає таким гуглерам, як я, які читають лише заголовок.
Ad Infinitum

29
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

Дякую Андреасу за редагування, можливо, це питання також допомагає: stackoverflow.com/questions/4014535/vs-and-vs
Torres

11

Це залежить від типу аргументів ...

Для цілих аргументів єдиний амперсанд ("&") є оператором "біт-розумний І". Подвійний амперсанд ("&&") не визначається нічим, крім двох булевих аргументів.

Для булевих аргументів одиничний амперсанд являє собою (безумовний) "логічний І" оператор, тоді як подвійний амперсанд ("&&") є "умовно-логічним оператором AND". Це означає, що одиночна амперсанда завжди оцінює обидва аргументи, тоді як подвійна амперсанда оцінює другий аргумент лише тоді, коли перший аргумент є істинним.

Для всіх інших типів та комбінацій аргументів повинна виникнути помилка часу компіляції.


9

&& - оператор короткого замикання, тоді як & - оператор AND.

Спробуйте це.

    String s = null;
    boolean b = false & s.isEmpty(); // NullPointerException
    boolean sb = false && s.isEmpty(); // sb is false

7

це як зазначено в JLS (15.22.2) :

Коли обидва операнди &, ^, або | оператора типу булевого або булевого типу, тоді видом побітового оператора вираз є булевим. У всіх випадках операнди за необхідності підлягають розгорнутому перетворенню (§5.1.8).

Для & значення результату є істинним, якщо обидва значення операнда є істинними; в іншому випадку результат хибний.

Для ^ значення результату вірно, якщо значення операндів різні; в іншому випадку результат хибний.

Для | значення результату є помилковим, якщо обидва значення операнда хибні; в іншому випадку результат правдивий.

«Трюк» полягає в тому, що &це оператор побітових операцій , а також логічний оператор логічного типу . То чому б ні, розглядаючи це як приклад для перевантаження оператора, є розумним.


7

Я думаю, що моя відповідь може бути зрозумілішою:

Існує дві відмінності між &та &&.

Якщо вони використовуються як логічні І

&і &&може бути логічним AND, коли &або &&ліве і праве вираз результат все вірно, весь результат операції може бути правдою.

коли &і &&як логічно AND, є різниця:

при використанні &&як логічному AND, якщо результат лівого виразу хибний, правий вираз не буде виконуватися.

Візьмемо приклад:

String str = null;

if(str!=null && !str.equals("")){  // the right expression will not execute

}

Якщо використовується &:

String str = null;

if(str!=null & !str.equals("")){  // the right expression will execute, and throw the NullPointerException 

}

Ще один приклад:

int x = 0;
int y = 2;
if(x==0 & ++y>2){
    System.out.print(“y=”+y);  // print is: y=3
}

int x = 0;
int y = 2;
if(x==0 && ++y>2){
    System.out.print(“y=”+y);  // print is: y=2
}

& може використовуватися як бітовий оператор

&може використовуватися як бітовий ANDоператор, &&не може.

Оператор побітового AND "&" виробляє 1, якщо і тільки якщо обидва біта в його операндах дорівнюють 1. Однак, якщо обидва біта дорівнюють 0 або обидва біта відрізняються, цей оператор видає 0. Щоб бути більш точним розрядним способом І оператор "&" повертає 1, якщо будь-який з двох бітів дорівнює 1, і він повертає 0, якщо будь-який з бітів дорівнює 0. 

На сторінці вікі:

http://www.roseindia.net/java/master-java/java-bitwise-and.shtml


4

'&&': - оператор Logical AND видає булеве значення true або false на основі логічного співвідношення його аргументів.

Наприклад: - Condition1 && Condition2

Якщо Condition1 є хибним, то (Condition1 && Condition2) завжди буде помилковим, тому причина цього логічного оператора також відома як Оператор короткого замикання, оскільки не оцінює іншу умову. Якщо Condition1 хибний, то оцінювати Condtiton2 не потрібно.

Якщо Condition1 вірно, то оцінюється Condition2, якщо це правда, то загальний результат буде істинним, інакше буде хибним.

'&': - є побітним І Оператором. Це дає один (1) у виході, якщо обидва вхідні біти є одним. В іншому випадку він виробляє нуль (0).

Наприклад:-

int a = 12; // двійкове представлення 12 становить 1100

int b = 6; // двійкове представлення 6 дорівнює 0110

int c = (a & b); // двійкове представлення (12 & 6) - 0100

Значення c дорівнює 4.

Для довідки зверніться до цього http://techno-terminal.blogspot.in/2015/11/difference-between-operator-and-operator.html


3

&&і ||називаються операторами короткого замикання. Коли вони використовуються, для ||- якщо перший операнд оцінює до true, то решта операндів не оцінюються. Для &&- якщо перший операнд оцінює false, решта з них взагалі не оцінюються.

тому if (a || (++x > 0))в цьому прикладі змінна x не збільшуватиметься, якщо вона була true.


3

Що стосується булевих, різниця у виході між ними не існує. Ви можете поміняти місцями && та & або || та | і це ніколи не змінить результату вашого вираження.

Різниця полягає в сцені, де інформація обробляється. Коли ви правильний вираз "(a! = 0) & (b! = 0)" для a = 0 і b = 1, відбувається таке:

left side: a != 0 --> false
right side: b 1= 0 --> true
left side and right side are both true? --> false
expression returns false

Коли ви пишете вираз, (a != 0) && ( b != 0)коли a = 0 і b = 1, відбувається таке:

a != 0 -->false
expression returns false

Менше кроків, менша обробка, краще кодування, особливо при виконанні багатьох булевих виразів або складних аргументів.


2
Це змінить загальний результат виразу, якщо операнди мають побічні ефекти.
Маркіз Лорнський

3

Окрім && та || будучи коротким замиканням, також враховуйте пріоритет оператора при змішуванні двох форм. Я думаю, що не всім буде очевидно, що результат1 та результат2 містять різні значення.

boolean a = true;
boolean b = false;
boolean c = false;

boolean result1 = a || b && c; //is true;  evaluated as a || (b && c)
boolean result2 = a  | b && c; //is false; evaluated as (a | b) && c

0

& є побітним оператором плюс використовується для перевірки обох умов, оскільки іноді нам потрібно оцінити обидві умови. Але & & логічний оператор переходить до другої умови, коли перша умова дає істину.


0

всі відповіді є great, і здається, що noвідповіді більше, is needed але я просто виграв, щоб зазначити щось про &&оператор, що називаєтьсяdependent condition

У виразах, що використовують оператор &&, умова - це будемо називати - dependent conditionможе знадобитися, щоб інша умова була правдивою, щоб оцінка залежної умови була значимою.

У цьому випадку залежна умова повинна бути поставлена ​​після оператора &&, щоб запобігти помилкам.

Розглянемо вираз (i != 0) && (10 / i == 2). Залежна умова (10 / i == 2)має оператора , щоб запобігти можливості поділу на нуль.appear after&&

ще один приклад (myObject != null) && (myObject.getValue() == somevaluse)

а інша справа: &&і ||називається оцінкою короткого замикання з - за другим аргумент виконується або оцінював аргумент робить , щоб зonly iffirstnot sufficedeterminevalueexpression

Посилання: Java ™ Як програмувати (ранні об’єкти), десяте видання

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.