В чем разница между & и && в Java?

168

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

Недавно я узнал, что &оператор также может использоваться для проверки того, являются ли оба его булевых операнда trueединственным отличием в том, что он проверяет операнд RHS, даже если операнд LHS имеет значение false.

Является ли &внутренне перегруженный оператор в Java? Или за этим стоит какая-то другая концепция?

Сообщество
источник
Double выполняет ярлык, если это возможно.
Николас Гамильтон

Ответы:

278

& <- проверяет оба операнда
&& <- прекращает оценку, если первый операнд оценивается как ложный, так как результат будет ложным

(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) оценивает как ложное, все это непосредственно оценивается как ложное без оценки (1/x > 1).

РЕДАКТИРОВАТЬ:

exprA | exprB<- это значит оценить, exprAзатем оценить, exprBзатем сделать |.

exprA || exprB<- это значит оценивать exprAи только если это falseпотом оценивать exprBи делать ||.

ITroubs
источник
7
Какова причина, чтобы написать один & или | в если заявление? Это никогда не будет быстрее, чем && и ||. Почему мы хотим проверить второе условие, если у нас уже есть ответ? Можете ли вы привести и реалистичный пример, пожалуйста?
Michu93
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 Это помогает таким же гуглерам, как я, которые читают только название.
Объявление 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) :

Когда оба операнда a, ^ или | оператор имеет тип boolean или Boolean, тогда тип выражения побитового оператора является логическим. Во всех случаях операнды подлежат распаковке преобразования (§5.1.8) по мере необходимости.

Для & значение результата равно true, если оба значения операнда имеют значение true; в противном случае результат ложен.

Для ^ значение результата равно true, если значения операндов различны; в противном случае результат ложен.

Для | значение результата равно false, если оба значения операнда имеют значение false; в противном случае результат верен.

«Хитрость» в том, что &это целочисленный побитовый оператор, а также логический логический оператор . Так почему бы и нет, рассмотрим это как пример для перегрузки операторов .

Андреас Долк
источник
7

Я думаю, что мой ответ может быть более понятным:

Есть два различия между &и &&.

Если они используют как логическое И

&и &&может быть логичным AND, когда результат выражения &or или &&left и right все true, весь результат операции может быть true.

когда &и &&как логично AND, есть разница:

при использовании в &&качестве логического AND, если результат левого выражения равен false, правое выражение не будет выполнено.

Возьмите пример:

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. Чтобы быть более точным в битовом выражении AND Оператор «&» возвращает 1, если любой из двух битов равен 1, и возвращает 0, если любой из битов равен 0. 

Со страницы вики:

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

самолет
источник
4

'&&': - это логический оператор AND, который выдает логическое значение true или false, основываясь на логической взаимосвязи его аргументов.

Например: - Условие1 && Условие2

Если Condition1 имеет значение false, то (Condition1 && Condition2) всегда будет иметь значение false, поэтому этот логический оператор также известен как оператор короткого замыкания, поскольку он не оценивает другое условие. Если Условие 1 ложно, тогда нет необходимости оценивать Condtiton2.

Если Условие1 истинно, то Условие2 оценивается, если оно истинно, тогда общий результат будет истинным, иначе он будет ложным.

'&': - является побитовым оператором AND. Он выдает единицу (1) на выходе, если оба входных бита равны единице. В противном случае он производит ноль (0).

Например:-

int a = 12; // двоичное представление 12 равно 1100

int b = 6; // двоичное представление 6 - 0110

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

Значение с 4.

для справки см. этот http://techno-terminal.blogspot.in/2015/11/difference-between-operator-and-operator.html

Сатиш
источник
3

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

поэтому if (a || (++x > 0))в этом примере переменная x не будет увеличена, если a была true.

ACV
источник
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

Кроме && и || будучи коротким замыканием, также учитывайте приоритет оператора при смешивании двух форм. Я думаю, что не всем сразу будет очевидно, что result1 и result2 содержат разные значения.

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
mgr326639
источник
0

& - побитовый оператор плюс, используемый для проверки обоих условий, потому что иногда нам нужно оценить оба условия. Но && логический оператор переходит во 2-е условие, когда первое условие дает true.

Ясир Шаббир Чоудхари
источник
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 ™ Как программировать (ранние объекты), десятое издание

Башир Аль-Момани
источник