Java에서 부울에 대한 비트 연산자의 영향


118

비트 연산자는 변수를 이동하고 비트 단위로 작동해야합니다. 정수, longs, char의 경우 이것은 의미가 있습니다. 이러한 변수는 크기에 따라 적용되는 값의 전체 범위를 포함 할 수 있습니다.

그러나 부울의 경우 부울에는 두 개의 값만 포함될 수 있습니다. 1 = 참 또는 0 = 거짓. 그러나 부울의 크기는 정의되지 않았습니다. 바이트만큼 크거나 조금 작을 수 있습니다.

부울에 비트 연산자를 사용하면 어떤 효과가 있습니까? JVM은 본질적으로 그것을 일반 논리 연산자로 변환하고 계속 진행합니까? 작업을 위해 부울을 단일 비트 엔티티로 취급합니까? 아니면 부울 크기와 함께 결과가 정의되지 않았습니까?


1
부울에 비트 연산자를 사용할 수 없다고 생각합니다. 숫자에만. 나는 ~ 작동하지 않을 것이라고 확신합니다, 나는 다른 운영자에 대해 무엇인지 모릅니다.
Martijn Courteaux 2009

4
당신은 그들 중 일부를 사용할 수 있습니다. 우리는 방금 | 레거시 코드에서 사용됩니다. 우리는 그것을 제거하고 있지만이 코드는 컴파일되고 작동했습니다.
Daniel Bingham

9
하나는 단락되고 다른 하나는 단락되어 있지 않기 때문에 (mobrule의 답변 참조), | ~에게 || 원래의 프로그래머가 항상 실행하려고했던 부작용이 후속 부울 표현식에 없는지 확인할 수 있습니다.
John M Gant

답변:


122

연산자 &,, ^|연산자는 피연산자가 기본 정수 유형 인 경우 비트 연산자입니다. 피연산자가 부울이고 후자의 경우 동작이 지정된 경우 논리 연산자입니다. 자세한 내용은 Java 언어 사양 의 섹션 15.22.2 를 참조하십시오.


57
특히 & 및 ^ 및 | 비 단락 논리 부울 연산자입니다.
Ken

14
다음은 위에서 언급 한 섹션에 대한 직접 링크입니다. docs.oracle.com/javase/specs/jls/se7/html/…
Andy Thomas

위의 내용이 사실 인 경우 ideone.com/oGSF7c 가 널 포인터 예외를 발생시키는 이유는 무엇입니까? 경우 |=운영자가 논리적이고, 프로그램은 실행되지 말았어야 x.getValue()지시를.
ikromm

1
@JohnKrommidas, 귀하의 x가 null이므로 NullPointerException이 발생합니다. 인스턴스화해야합니다.
Ben

4
@Ben, @Ken이 말했듯이 논리는 단락되지 않으므로 두 번째 부분이 평가됩니다. 따라서 a || x.foo()x가 null이면 안전하지만 a | x.foo()그렇지 않습니다. |=와 동일한 규칙을 따릅니다 |.
Michael Smith

86

비트 연산자를 사용하면 단락 동작을 피할 수 있습니다.

boolean b = booleanExpression1() && booleanExpression2();
boolean b = booleanExpression1() & booleanExpression2();

경우 booleanExpression1()들을 평가가 false다음
booleanExpression2()첫 번째 경우 및 평가되지 않는다
booleanExpression2()(그리고 어떤 부작용이있을 수있다)이 되는 두 번째 경우에 평가,


2
그리고 비트 연산은 일반적으로 단락 회로보다 빠르게 수행됩니다 (평가가 단순 할 경우)
rds

1
비트 단위 &는 더 빠르지 만 두 번째 함수에 대한 호출은 다음을 사용하여 무시할 수 있습니다.&&
NatNgs

20

다른 답변으로 덮여 것 이상으로, 그것의 가치는 그것을 지적 &&하고 ||다른 우선 순위를 가지고 &|.

우선 순위 테이블 에서 추출 합니다 (가장 높은 우선 순위가 맨 위에 있음).

bitwise AND                 &
bitwise exclusive OR        ^
bitwise inclusive OR        |
logical AND                 &&
logical OR                  ||

이것이 당신에게 어떤 의미입니까?

&and |또는 only &&and 중 하나만 고수하는 한 절대 아무것도 아닙니다 ||.

그러나 ( 우선 순위가 |낮은와 &&달리 ||)보다 우선 순위 가 높기 때문에 자유롭게 혼합하면 예상치 못한 동작이 발생할 수 있습니다.

그래서 a && b | c && d과 동일 a && (b | c) && d,
반대를 a && b || c && d하는 것(a && b) || (c && d) .

동일하지 않다는 것을 증명하기 위해 진리표에서 발췌 한 내용을 고려하십시오.

a | b | c | d | (b|c) | (a&&b) | (c&&d) | a && (b|c) && d | (a&&b) || (c&&d)
F | T | T | T |   T   |   F    |    T   |         F       |        T
                                                  ^                ^
                                                  |- not the same -|

OR이 AND보다 우선 순위를 높이 려면 and를 함께 사용할 있지만 권장되지는 않습니다.|&&

그러나 다른 기호를 사용할 때마다 우선 순위를 명확히하기 위해 괄호 안에 넣어야합니다 (a && b) || c( 예 : 우선 순위를 명확히하는 대괄호) a && b && c(대괄호 필요 없음).


3

그것이 효과가 있더라도 당신은 그것을하지 말아야합니다. 언어 사양은 두 피연산자가 기본 정수 유형이거나 둘 다 부울 유형 인 경우에만 비트 연산자를 정의합니다. 다른 경우에는 결과가 정의되지 않았습니다.

http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5228


문제 부울에 관한 것이지, 프리미티브 나 프리미티브와 부울의 혼합에 관한 것이 아닙니다.
talonx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.