자바 논리 연산자 단락


100

어떤 세트가 단락되고 복잡한 조건식이 단락된다는 것은 정확히 무엇을 의미합니까?

public static void main(String[] args) {
  int x, y, z;

  x = 10;
  y = 20;
  z = 30;

  // T T
  // T F
  // F T
  // F F

  //SET A
  boolean a = (x < z) && (x == x);
  boolean b = (x < z) && (x == z);
  boolean c = (x == z) && (x < z);
  boolean d = (x == z) && (x > z);
  //SET B    
  boolean aa = (x < z) & (x == x);
  boolean bb = (x < z) & (x == z);
  boolean cc = (x == z) & (x < z);
  boolean dd = (x == z) & (x > z);

}

답변:


244

&&||이 필요하지 않은 의미 사업자 "단락", 그들은 오른쪽을 평가하지 않습니다.

&|논리 연산자로 사용하는 경우 사업자는, 항상 양쪽을 평가합니다.

각 오퍼레이터에 대해 단 하나의 단락 사례가 있으며 다음과 같습니다.

  • false && ...-결과는 false거기의 값에 관계없이 결과가 될 수 있기 때문에 오른쪽이 무엇인지 알 필요가 없습니다
  • true || ...-결과는 true거기의 값에 관계없이 결과가 될 수 있기 때문에 오른쪽이 무엇인지 알 필요가 없습니다

간단한 예에서 동작을 비교해 보겠습니다.

public boolean longerThan(String input, int length) {
    return input != null && input.length() > length;
}

public boolean longerThan(String input, int length) {
    return input != null & input.length() > length;
}

두 번째 버전은 비 단락 연산자를 사용 &하고 NullPointerExceptionif inputis 를 throw null하지만 첫 번째 버전은 false예외없이 반환 됩니다.


9
이 답변을 조금 확장하고 싶습니다. & = 연산자는 x = x & 표현식의 약자이므로 단락되지 않습니다. | = 연산자도 마찬가지입니다.
Stormcloud

11
제가 강조하고 싶은 한 가지는 | and &는 이항 연산자이고, &&와 || 조건부 (논리) 연산자입니다. | 그리고 & & & & || 부울에서만 작동합니다.
신화

1
오른쪽의 표현식을 평가하지 않을뿐만 아니라 평가할 항목이있는 코드도 실행되지 않습니다. 이것은 부작용이 발생하는지 여부를 이해하는 중요한 지점입니다.
mckenzm

@mckenzm 평가와 실행의 차이점은 무엇입니까?
Kronen

@Kronen Execution은 평가 이상의 결과를 초래할 수 있으며 예외 또는 지연과 같은 부작용이 발생할 수 있습니다.이 예와 관련이없는 비용을 지불하겠습니다.
mckenzm

9

SET A는 단락 부울 연산자를 사용합니다.

부울 연산자의 맥락에서 '단락'이 의미하는 것은 일련의 부울 b1, b2, ..., bn에 대해 단락 회로 버전은 이러한 부울 중 첫 번째가 참이되는 즉시 평가를 중단한다는 것입니다 (|| ) 또는 false (&&).

예를 들면 :

// 2 == 2 will never get evaluated because it is already clear from evaluating
// 1 != 1 that the result will be false.
(1 != 1) && (2 == 2)

// 2 != 2 will never get evaluated because it is already clear from evaluating
// 1 == 1 that the result will be true.
(1 == 1) || (2 != 2)

이 경우에 해당 &&하고 ||다르게 작동하며 true를 반환하는 첫 번째 피연산자에 대한 평가를 중단 하도록 지정하십시오 .)
fge

1
사실, 모두 정말 완료하기 위해 &&, ||, &그리고 |왼쪽에서 오른쪽으로 평가합니다. 부울 세트 b1, b2, ..., bn의 경우 단락 회로 버전은 이러한 부울 중 첫 번째 부울이 참 ( ||) 또는 거짓 ( &&) 일 때 평가를 중단 합니다. Bah, 원칙이 있습니다;)
fge

@fge : 네, 물론 맞습니다. 당신의 정의는 내 것보다 정확합니다. 귀하의 의견에있는 문장으로 제 답변을 업데이트했습니다. 괜찮 으시길 바랍니다.
afrischke

걱정하지 마세요. 지식이 공유되지 않으면 가치가 없습니다.
fge

4

단락은 첫 번째 운영자가 최종 결과를 결정하는 경우 두 번째 운영자를 확인하지 않음을 의미합니다.

예 : True || 그릇된

||의 경우, 우리가 필요로 하는 것은 참 이되는면 중 하나입니다 . 따라서 왼쪽이 참이면 오른쪽을 확인하는 데 아무런 의미가 없으므로 전혀 확인되지 않습니다.

마찬가지로 False && True

&&의 경우 양쪽 모두 True가되어야합니다. 따라서 왼쪽이 False이면 오른쪽을 검사 할 필요가 없으며 답은 False가되어야합니다. 따라서 그것은 전혀 확인되지 않을 것입니다.


4
boolean a = (x < z) && (x == x);

이런 종류의 경우 의미 단락 것이다 (x < z)평가되지 않습니다 다음 후자 FALSE로는, a그렇지 않으면 false 것 &&또한 평가합니다 (x == x).

& 비트 연산자이지만 단락되지 않는 부울 AND 연산자이기도합니다.

다음과 같이 테스트 할 수 있습니다 (각 사례에서 메서드가 호출되는 횟수 참조).

public static boolean getFalse() {
    System.out.println("Method");
    return false;
}

public static void main(String[] args) {
    if(getFalse() && getFalse()) { }        
    System.out.println("=============================");        
    if(getFalse() & getFalse()) { }
}

-1 당신의 대답은 그 제안 &입니다 비트 단위 연산자,하지만 그건 사실이 아니다. 그것은이다 또한 부울 "또는"연산자.
Bohemian

@Bohemian : 고마워요. true & false거짓으로 평가됩니다. 이 "부울"또는 "연산자"를 설명해 주시겠습니까? 나는 당신이 말하려는 것을 얻지 못할 수도 있습니다.
Bhesh Gurung

죄송합니다 - 나는 부울 의미 AND하지 OR! 즉, true & false유효한 구문입니다. -1 제거 :)
보헤미안

4

간단히 말해서, 단락 이란 답이 더 이상 바뀔 수 없다는 것을 알게되면 평가를 중단하는 것을 의미합니다. 예를 들어 논리 체인을 평가하고 해당 체인의 중간에서 ANDa를 발견하면 FALSE체인의 나머지 표현식 값에 관계없이 결과가 거짓임을 알 수 있습니다. 일련의 ORs도 마찬가지입니다 . 일단을 발견하면 TRUE바로 답을 알 수 있으므로 나머지 표현식 평가를 건너 뛸 수 있습니다.

&&대신 &||대신을 사용하여 단락을 원한다는 것을 Java에 표시합니다 |. 게시물의 첫 번째 세트는 단락입니다.

이것은 CPU 사이클을 절약하려는 시도 이상입니다.

if (mystring != null && mystring.indexOf('+') > 0) {
    ...
}

단락은 올바른 작동과 충돌 (mystring이 null 인 경우)의 차이를 의미합니다.


2

Java는 대부분의 다른 컴퓨터 언어에서 찾을 수없는 두 가지 흥미로운 부울 연산자를 제공합니다. AND 및 OR의 이러한 보조 버전을 단락 논리 연산자라고 합니다. 앞의 표에서 볼 수 있듯이 OR 연산자는 B가 무엇이든 A가 참이면 참이됩니다.

마찬가지로 AND 연산자는 B가 무엇이든간에 A가 거짓이면 거짓이됩니다. 이러한 연산자 의 and 형식 대신 ||&&형식 을 사용하는 경우 Java는 오른쪽 피연산자를 단독으로 평가하지 않습니다. 이것은 오른쪽 피연산자가 제대로 작동하기 위해 왼쪽 피연산자가 true 또는 false에 의존 할 때 매우 유용합니다.|&

예를 들어, 다음 코드 조각은 단락 연산이 평가 전에 유효한지 확인하기 위해 단락 논리 평가를 활용하는 방법을 보여줍니다.

if ( denom != 0 && num / denom >10)

단락 형식의 AND ( &&)가 사용되기 때문에 런타임 예외가 0으로 나눌 위험이 없습니다. 이 코드 줄이 단일 &버전의 AND를 사용하여 작성 되었다면 양쪽을 모두 평가해야하므로 denom0 일 때 런타임 예외 가 발생합니다.

부울 논리와 관련된 경우 AND 및 OR의 단락 형식을 사용하여 단일 문자 버전은 비트 연산 전용으로 남겨 두는 것이 표준 관행입니다. 그러나이 규칙에는 예외가 있습니다. 예를 들어, 다음 문을 고려하십시오.

 if ( c==1 & e++ < 100 ) d = 100;

여기서 단일 &을 사용 하면 1과 같은지 e여부에 증분 연산이 적용됩니다 c.


2

논리 OR :-피연산자 중 하나 이상이 true로 평가되면 true를 반환합니다. OR 연산자를 적용하기 전에 두 피연산자가 모두 평가됩니다.

Short Circuit OR :-왼쪽 피연산자가 true를 반환하면 오른쪽 피연산자를 평가하지 않고 true를 반환합니다.


2

연산자 &&&연산자 사이에는 몇 가지 차이점이 있습니다. 같은 차이에 적용 |하고 ||. 명심해야 할 가장 중요한 것은 즉 &&A는 논리적 동안 만 부울 피연산자에 적용 연산자 &A는 비트 정수 타입뿐만 아니라 논리 값에 적용 연산자.

논리 연산, 당신 때문에 어떤 경우에는 (의 첫 번째 피연산자 같은 단락을 할 수 &&있는 false, 또는의 첫 번째 피연산자 ||true), 당신은 표현의 나머지 부분을 평가 할 필요가 없습니다. 이것은 null파일이나 메서드에 액세스하기 전에 확인하고 나누기 전에 잠재적 인 0을 확인하는 것과 같은 작업을 수행하는 데 매우 유용 합니다. 복잡한 식의 경우 식의 각 부분이 동일한 방식으로 재귀 적으로 평가됩니다. 예를 들어, 다음과 같은 경우 :

(7 == 8) || ( (1 == 3) && (4 == 4))

강조된 부분 만 평가됩니다. 전자 컴퓨터 ||경우, 첫번째 확인 7 == 8입니다 true. 만약 그렇다면, 오른쪽은 완전히 건너 뛸 것입니다. 오른쪽 1 == 3은 인 경우에만 확인합니다 false. 그렇기 때문에 4 == 4확인할 필요가 없으며 전체 표현식이로 평가됩니다 false. true예를 들어 7 == 7대신 왼쪽이 이면 7 == 8전체 ||표현식이 true관계 가 없기 때문에 오른쪽 전체를 건너 뜁니다 .

비트 연산을 사용하면 실제로 비트를 결합하기 때문에 모든 피연산자를 평가해야합니다. 부울은 Java에서 사실상 1 비트 정수이며 (내부 작동 방식에 관계없이) 특별한 경우에 비트 연산자에 대해 단락을 수행 할 수 있다는 것은 우연의 일치입니다. 일반 정수 &또는 |연산을 단락시킬 수없는 이유 는 일부 비트가 피연산자에서 켜져 있고 일부가 꺼져있을 수 있기 때문입니다. 같은 것은 1 & 20을 산출하지만 두 피연산자를 모두 평가하지 않고는 그것을 알 수있는 방법이 없습니다.


1
if(demon!=0&& num/demon>10)

AND (&&)의 단락 형태가 사용되므로 demon가 0 일 때 런타임 예외가 발생할 위험이 없습니다.

Ref. Herbert Schildt의 Java 2 Fifth Edition

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.