Odpowiedzi:
Są to operatory bitowe AND i bitowe OR.
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
Podziękowania dla Carlosa za wskazanie odpowiedniej sekcji w specyfikacji języka Java ( 15.22.1 , 15.22.2 ) dotyczącej różnych zachowań operatora na podstawie jego danych wejściowych.
Rzeczywiście, gdy oba wejścia są logiczne, operatory są uważane za logiczne operatory boolowskie i zachowują się podobnie do operatorów warunkowych-i ( &&
) i warunkowych-lub ( ||
) z wyjątkiem faktu, że nie powodują zwarcia, więc poniższe jest bezpieczne :
if((a != null) && (a.something == 3)){
}
To nie jest:
if((a != null) & (a.something == 3)){
}
„Zwarcie” oznacza, że operator niekoniecznie sprawdza wszystkie warunki. W powyższych przykładach, &&
sprawdzi drugi warunek tylko wtedy, gdy a
nie jest null
(w przeciwnym razie cała instrukcja zwróci fałsz, a zatem i tak byłoby dyskusyjne sprawdzenie następujących warunków), więc stwierdzenie a.something
nie spowoduje wyjątku lub jest uważane za „bezpieczne . ”
&
Operatora zawsze sprawdza każdy stan w klauzuli więc w powyższych przykładach, a.something
można ocenić, kiedy a
w rzeczywistości jest null
to wartość, zwiększając wyjątek.
Myślę, że mówisz o logicznym znaczeniu obu operatorów, tutaj masz podsumowanie tabeli:
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
Ocena zwarcia, ocena minimalna lub ocena McCarthy'ego (za Johnem McCarthym) to semantyka niektórych operatorów logicznych w niektórych językach programowania, w których drugi argument jest wykonywany lub szacowany tylko wtedy, gdy pierwszy argument nie wystarcza do określenia wartości argumentu wyrażenie: kiedy pierwszy argument funkcji AND ma wartość fałsz, ogólna wartość musi być fałszywa; a kiedy pierwszy argument funkcji LUB ma wartość true, ogólna wartość musi być prawdziwa.
Not Safe oznacza, że operator zawsze sprawdza każdy warunek w klauzuli, więc w powyższych przykładach 1 / x może zostać oszacowane, gdy x jest w rzeczywistości wartością 0, co powoduje wyjątek.
Wiem, że jest tu wiele odpowiedzi, ale wszystkie wydają się nieco zagmatwane. Po przeprowadzeniu pewnych badań z przewodnika do nauki języka Java, opracowałem trzy różne scenariusze, kiedy używać && lub &. Trzy scenariusze to logiczne AND , bitowe AND i logiczne AND .
ORAZ logiczne: ORAZ
logiczne (aka ORAZ warunkowe) używa operatora && . To skrótowe znaczenie: jeśli lewy operand jest fałszywy, to prawy operand nie będzie oceniany.
Przykład:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
W powyższym przykładzie wartość wypisywana na konsoli x będzie wynosić 0, ponieważ pierwszy operand w instrukcji if jest fałszywy, stąd java nie ma potrzeby obliczania (1 == ++ x), dlatego x nie zostanie obliczone.
Bitowe AND: Bitowe AND używa operatora & . Służy do wykonywania operacji bitowej na wartości. O wiele łatwiej jest zobaczyć, co się dzieje, patrząc na operacje na liczbach binarnych, np .:
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
Jak widać na przykładzie, gdy binarne reprezentacje liczb 5 i 12 są ustawione w jednej linii, wówczas preformowane bitowe AND da tylko liczbę binarną, w której ta sama cyfra w obu liczbach będzie miała 1. Stąd 0101 i 1100 == 0100. Która dziesiętnie to 5 i 12 == 4.
Boolean AND: Teraz logiczny operator AND zachowuje się podobnie i inaczej zarówno w przypadku bitowego AND, jak i logicznego AND. Lubię o tym myśleć jako o wykonywaniu bitowego AND pomiędzy dwiema wartościami logicznymi (lub bitami), dlatego używa operatora & . Wartości logiczne mogą być również wynikiem wyrażenia logicznego.
Zwraca wartość true lub false, podobnie jak logiczne AND, ale w przeciwieństwie do logicznego AND nie jest zwarty. Powodem jest to, że aby wykonać to bitowe AND, musi znać wartość zarówno lewego, jak i prawego operandu. Oto były:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Teraz, gdy instrukcja if zostanie uruchomiona, wyrażenie (1 == ++ x) zostanie wykonane, nawet jeśli lewy operand jest fałszywy. Stąd wartość wydrukowana dla x będzie wynosić 1, ponieważ została zwiększona.
Dotyczy to również logicznego OR (||), bitowego OR (|) i logicznego OR (|) Mam nadzieję, że to wyjaśni pewne nieporozumienia.
to preform that bitwise AND, it must know the value of both left and right operands
Nie brzmi to dla mnie dobrze. Aby wykonać BITWISE AND
operand, nie musisz znać właściwego operandu, aby móc obliczyć wynik, jeśli lewy operand jest FALSE
. Co pan wyjaśnić jest poprawna, ale rozumowanie Ci państwo nie wydaje się więc, przynajmniej dla mnie ..
Operatory && i || powodują zwarcia, co oznacza, że nie będą oceniać wyrażenia po prawej stronie, jeśli wartość wyrażenia po lewej stronie jest wystarczająca do określenia wyniku.
& i | zapewniają taki sam wynik jak && i || operatorzy. Różnica polega na tym, że zawsze oceniają obie strony wyrażenia, gdzie jako && i || przestań oceniać, czy pierwszy warunek wystarczy, aby określić wynik.
&&
ocenia oba wyniki, a ||
zwraca tylko wtedy, gdy pierwszy warunek jest prawdziwy.
( 2 & 4 )
szacuje do false
, podczas gdy ( 2 && 4 )
szacuje do true
. Jak dokładnie to jest ten sam wynik?
2 & 4
daje w wyniku liczbę całkowitą, a nie wartość logiczną (w tym przypadku zero). 2 && 4
nie kompiluje && akceptuje tylko wartości logiczne. Java nie pozwala na mieszanie wartości logicznych i ints: zero nie jest false
, false
nie jest zero ...
&&
oblicza drugi operand tylko wtedy, gdy pierwszy operand jest true
.
W Javie pojedyncze operatory &, |, ^,! zależą od operandów. Jeśli oba operandy są liczbami całkowitymi, wykonywana jest operacja bitowa. Jeśli oba są wartościami logicznymi, wykonywana jest operacja „logiczna”.
Jeśli oba operandy są niezgodne, zgłaszany jest błąd czasu kompilacji.
Podwójne operatory &&, || zachowują się podobnie do swoich pojedynczych odpowiedników, ale oba operandy muszą być wyrażeniami warunkowymi, na przykład:
if ((a <0) && (b <0)) {...} lub podobnie, if ((a <0) || (b <0)) {...}
źródło: programowanie java lang 4th ed
&
i |
są operatorami bitowymi na typach całkowitych (np. int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
i ||
działają tylko na wartościach logicznych (i zwarciach, jak już powiedziały inne odpowiedzi).
&
i |
są także operatorami logicznymi na typach boolowskich.
Może warto wiedzieć, że bitowe operatory AND i bitowe OR są zawsze oceniane przed warunkowym AND i warunkowym OR, używanymi w tym samym wyrażeniu.
if ( (1>2) && (2>1) | true) // false!
&&; || są operatorami logicznymi… zwarciem
&; | są logicznymi operatorami logicznymi .... Bez zwarć
Przechodzenie do różnic w wykonywaniu wyrażeń. Operatory bitowe oceniają obie strony niezależnie od wyniku lewej strony. Ale w przypadku obliczania wyrażeń za pomocą operatorów logicznych ocena wyrażenia prawej ręki zależy od stanu lewej ręki.
Na przykład:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
To wypisze i = 26; j = 25, Ponieważ pierwszy warunek jest fałszywy, stan prawej ręki jest pomijany, ponieważ wynik i tak jest fałszywy, niezależnie od stanu prawej strony. (zwarcie)
int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Ale to wypisze i = 26; j = 26,
Jeśli wyliczane jest wyrażenie zawierające operator boolowski & , oceniane są oba operandy. Następnie operator & jest stosowany do operandu.
Podczas obliczania wyrażenia zawierającego operator && obliczany jest pierwszy operand. Jeśli wynik pierwszego operandu to fałsz, ocena drugiego argumentu jest pomijana.
Jeśli pierwszy operand zwraca wartość true, to obliczany jest drugi operand. Jeśli drugi operand zwraca wartość true, wówczas operator && jest następnie stosowany do pierwszego i drugiego operandu.
Podobne dla | i ||.
Chociaż podstawową różnicą jest to, że &
jest używany do operacji bitowe głównie na long
, int
lub byte
gdzie może on być stosowany do rodzaju maski, wyniki mogą się różnić, nawet jeśli używać go zamiast logiczne &&
.
Różnica jest bardziej zauważalna w niektórych scenariuszach:
Pierwsza kwestia jest dość prosta, nie powoduje żadnych błędów, ale zajmuje więcej czasu. Jeśli masz kilka różnych sprawdzeń w jednej instrukcji warunkowej, umieść te, które są tańsze lub z większym prawdopodobieństwem zawiodą, po lewej stronie.
Po drugie, zobacz ten przykład:
if ((a != null) & (a.isEmpty()))
To się nie powiedzie null
, ponieważ ocena drugiego wyrażenia daje NullPointerException
. Operator logiczny &&
jest leniwy, jeśli lewy operand jest fałszywy, wynik jest fałszywy, niezależnie od tego, jaki jest prawy operand.
Przykład trzeciego punktu - powiedzmy, że mamy aplikację, która korzysta z DB bez żadnych wyzwalaczy ani kaskad. Zanim usuniemy obiekt budynku, musimy zmienić budynek obiektu działu na inny. Powiedzmy też, że status operacji jest zwracany jako wartość logiczna (prawda = sukces). Następnie:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Spowoduje to ocenę obu wyrażeń, a tym samym usuwa kompilację, nawet jeśli aktualizacja działu nie powiodła się z jakiegoś powodu. Dzięki &&
temu działa zgodnie z przeznaczeniem i zatrzymuje się po pierwszej awarii.
Jeśli chodzi o a || b
to, jest to równoważne !(!a && !b)
, zatrzymuje się, jeśli a
jest prawdziwe, nie potrzeba więcej wyjaśnień.