답변:
비트 AND 및 비트 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
입력을 기반으로 한 연산자의 다양한 동작과 관련하여 Java 언어 사양 ( 15.22.1 , 15.22.2 ) 에서 적절한 섹션을 지적한 Carlos에게 감사드립니다 .
실제로 두 입력이 모두 부울이면 연산자는 부울 논리 연산자로 간주 되며 다음이 안전하지만 단락되지 않는다는 점을 제외하면 &&
조건부 및 ( ) 및 조건부 또는 ( ||
) 연산자 와 유사하게 작동 합니다. :
if((a != null) && (a.something == 3)){
}
이것은 아니다:
if((a != null) & (a.something == 3)){
}
"단락"은 작업자가 모든 조건을 검사 할 필요는 없음을 의미합니다. 위의 예에서, &&
경우에만 두 번째 조건을 검사 할 a
수 없습니다 null
(그렇지 않으면 전체 문이 false를 반환합니다, 어쨌든 조건에 따라 조사 할 논쟁 것)의 문 있도록 a.something
예외를 발생하지 않을 것이다, 또는 "안전한 것으로 간주됩니다 . "
&
작업자는 항상 상기의 예에서, 상기 구문의 모든 조건을 검사 a.something
할 때 평가 될 수 a
사실 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
단락 평가 , 최소 평가 또는 McCarthy 평가 (John McCarthy 이후)는 일부 프로그래밍 언어에서 두 번째 인수가 실행되거나 첫 번째 인수가 값을 결정하는 데 충분하지 않은 경우에만 평가되는 일부 부울 연산자의 의미입니다. 표현식 : AND 함수의 첫 번째 인수가 거짓으로 평가되면 전체 값은 거짓이어야합니다. OR 함수의 첫 번째 인수가 true로 평가되면 전체 값이 true 여야합니다.
안전하지 않음 은 연산자가 항상 절의 모든 조건을 검사 함을 의미하므로 위의 예에서 1 / x는 x가 실제로 0 값일 때 평가되어 예외가 발생할 수 있습니다.
여기에 많은 답변이 있다는 것을 알고 있지만 모두 약간 혼란스러워 보입니다. 그래서 Java oracle 학습 가이드에서 몇 가지 조사를 한 후 && 또는 &를 사용할 때 세 가지 시나리오를 생각해 냈습니다. 세 가지 시나리오는 논리 AND , 비트 AND 및 부울 AND 입니다.
논리적 AND :
논리 AND (일명 조건부 AND)는 && 연산자를 사용합니다 . 단락 된 의미입니다. 왼쪽 피연산자가 거짓이면 오른쪽 피연산자가 평가되지 않습니다.
예:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
위의 예에서 x의 콘솔에 인쇄 된 값은 if 문의 첫 번째 피연산자가 false이므로 java가 계산할 필요가 없으므로 (1 == ++ x) x가 계산되지 않기 때문에 0이됩니다.
비트 AND : 비트 AND는 & 연산자를 사용합니다 . 값에 대해 비트 연산을 수행하는 데 사용됩니다. 이진수에 대한 연산을 살펴보면 무슨 일이 일어나는지 보는 것이 훨씬 쉽습니다. 예 :
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의 이진 표현이 정렬되면 비트 AND preformed는 두 숫자의 동일한 숫자가 1 인 이진 숫자 만 생성합니다. 따라서 0101 & 1100 == 0100. 십진수로 5 & 12 == 4입니다.
부울 AND : 이제 부울 AND 연산자가 비트 AND 및 논리 AND 모두에 대해 유사하고 다르게 작동합니다. 나는 두 개의 부울 값 (또는 비트) 사이에 비트 AND를 미리 형성하는 것으로 생각하고 싶으므로 & 연산자를 사용합니다 . 부울 값은 논리식의 결과 일 수도 있습니다.
논리 AND와 매우 유사하게 true 또는 false 값을 반환하지만 논리 AND와 달리 단락되지 않습니다. 그 이유는 비트 AND를 수행하려면 왼쪽 및 오른쪽 피연산자의 값을 모두 알아야하기 때문입니다. 예를 들면 다음과 같습니다.
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
이제 if 문이 실행되면 왼쪽 피연산자가 false 인 경우에도 (1 == ++ x) 표현식이 실행됩니다. 따라서 x에 대해 인쇄 된 값은 증가했기 때문에 1이됩니다.
이것은 논리 OR (||), 비트 OR (|) 및 부울 OR (|)에도 적용됩니다. 이것이 약간의 혼란을 없애기를 바랍니다.
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
결과는 부울이 아닌 정수입니다 (이 경우 0). 2 && 4
컴파일되지 않고 && 부울 만 허용합니다. 0이 아닌 : 자바는 논리 값과의 int를 혼합 할 수 없습니다 false
, false
... 제로는 아니다
&&
단지 두 번째 피연산자를 평가 첫 번째 피연산자 인 경우 true
.
&
및 |
통합 유형에 대한 비트 연산자 (예입니다 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, 첫 번째 조건이 false이므로 오른쪽 조건에 관계없이 결과가 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 = 26,
기본적인 차이는 있지만 그 &
대부분에 비트 연산에 사용되는 long
, int
또는 byte
이 마스크의 종류에 사용할 수있는 당신의 논리 대신에 그것을 사용하는 경우에도 결과는 다를 수 있습니다 &&
.
차이는 일부 시나리오에서 더 두드러집니다.
첫 번째 요점은 매우 간단하며 버그를 일으키지 않지만 시간이 더 걸립니다. 하나의 조건문에 여러 가지 다른 검사가있는 경우 더 저렴하거나 실패 할 가능성이 더 높은 검사를 왼쪽에 두십시오.
두 번째 요점은 다음 예를 참조하십시오.
if ((a != null) & (a.isEmpty()))
이것은 실패 null
두번째 식을 평가하는 단계를 생성 같이 NullPointerException
. 논리 연산자 &&
는 게으르고 왼쪽 피연산자가 거짓이면 오른쪽 피연산자가 무엇이든 결과는 거짓입니다.
세 번째 요점의 예-트리거 또는 캐스케이드없이 DB를 사용하는 앱이 있다고 가정 해 보겠습니다. Building 객체를 제거하기 전에 Department 객체의 건물을 다른 건물로 변경해야합니다. 또한 작업 상태가 부울 (true = 성공)로 반환된다고 가정 해 보겠습니다. 그때:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
이는 두 식을 모두 평가하여 어떤 이유로 부서 업데이트가 실패하더라도 건물 제거를 수행합니다. 를 사용하면 &&
의도 한대로 작동하고 첫 번째 실패 후 중지됩니다.
의 경우 a || b
와 동일하며 !(!a && !b)
, a
true이면 중지 되며 더 이상 설명이 필요하지 않습니다.