[java] && (AND) 및 || IF 문에서 (또는)

다음 코드가 있습니다.

if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){
    partialHits.get(z).put(z, tmpmap.get(z));
}

partialHitsHashMap은 어디에 있습니까 ?
첫 번째 진술이 참이면 어떻게됩니까? Java가 여전히 두 번째 명령문을 점검합니까? 첫 번째 문이 true이기 때문에 HashMap에 주어진 키가 포함되어서는 안되므로 두 번째 문을 확인하면을 얻습니다 NullPointerException.
간단한 코드로, 다음 코드가 있다면

if(a && b)
if(a || b)

Java 는 첫 번째 경우 false b인지 확인 하고 두 번째 경우에는 true입니까?aa



답변

아니요, 평가되지 않습니다. 그리고 이것은 매우 유용합니다. 예를 들어, 문자열이 null인지 비어 있는지 테스트해야 할 경우 다음과 같이 작성할 수 있습니다.

if (str != null && !str.isEmpty()) {
  doSomethingWith(str.charAt(0));
}

또는 다른 방법으로

if (str == null || str.isEmpty()) {
  complainAboutUnusableString();
} else {
  doSomethingWith(str.charAt(0));
}

Java에 ‘단락’이 없으면 위의 코드 줄에서 많은 NullPointerException이 발생합니다.


답변

Java에는 5 가지 부울 비교 연산자가 있습니다. &, &&, |, ||, ^

& 및 &&는 “and”연산자입니다. | 그리고 || “or”연산자, ^은 “xor”

단일 값은 매개 변수 값을 확인하기 전에 값에 관계없이 모든 매개 변수를 확인합니다. 이중은 먼저 왼쪽 매개 변수와 해당 값을 확인하고 true( ||) 또는 false(&& )는 두 번째 그대로 둡니다. 컴파일 된 소리? 쉬운 예는 그것을 분명히해야합니다 :

모든 예에 대해 주어진다 :

 String aString = null;

과:

 if (aString != null & aString.equals("lala"))

평가가 완료되기 전에 두 매개 변수를 모두 확인하고 두 번째 매개 변수에 대해 NullPointerException이 발생합니다.

 if (aString != null && aString.equals("lala"))

첫 번째 매개 변수가 확인되고가 반환 false되므로 결과가 false어쨌든 두 번째 매개 변수가 확인되지 않습니다 .

OR에 대해서도 동일합니다.

 if (aString == null | !aString.equals("lala"))

NullPointerException도 발생합니다.

 if (aString == null || !aString.equals("lala"))

첫 번째 매개 변수가 확인되고가 반환 true되므로 결과가 true어쨌든 두 번째 매개 변수가 확인되지 않습니다 .

XOR은 두 매개 변수에 따라 다르므로 최적화 할 수 없습니다.


답변

아니요 확인되지 않습니다. 이 동작을 단락 평가 라고하며 Java를 포함한 여러 언어의 기능입니다.


답변

여기에있는 모든 대답은 훌륭하지만 이것이 어디에서 왔는지 설명하기 위해 이와 같은 질문에 대해서는 소스 : Java 언어 사양으로 이동하는 것이 좋습니다.

섹션 15:23, 조건부 연산자 (&&) 는 다음과 같이 말합니다.

&& 연산자는 & (§15.22.2)와 비슷하지만 왼쪽 피연산자의 값이 참인 경우에만 오른쪽 피연산자를 평가합니다. […] 런타임시 왼쪽 피연산자 표현식이 먼저 평가됩니다. […] 결과 값이 false이면 조건부 및 표현식의 값이 false이고 오른쪽 피연산자 표현식이 평가되지 않습니다. . 왼쪽 피연산자의 값이 true이면 오른쪽 표현식이 평가되고 […] 결과 값이 조건부 및 표현식의 값이됩니다. 따라서 &&는 부울 피연산자에서 &와 동일한 결과를 계산합니다. 오른쪽 피연산자 표현식이 항상이 아니라 조건부로 평가된다는 점만 다릅니다.

마찬가지로, 조건부 또는 연산자 (||) 섹션 15:24 는 다음과 같이 말합니다.

|| 연산자는 같다 | (§15.22.2), 왼쪽 피연산자의 값이 false 인 경우에만 오른쪽 피연산자를 평가합니다. […] 런타임에 왼쪽 피연산자 표현식이 먼저 평가됩니다. […] 결과 값이 true이면 조건부 또는 표현식의 값이 true이고 오른쪽 피연산자 표현식이 평가되지 않습니다. 왼쪽 피연산자의 값이 false이면 오른쪽 표현식이 평가됩니다. […] 결과 값은 조건부 또는 표현식의 값이됩니다. 따라서 || 와 동일한 결과를 계산합니다 | 부울 또는 부울 피연산자에서. 오른쪽 피연산자 표현식이 항상이 아니라 조건부로 평가된다는 점만 다릅니다.

약간 반복적이지만, 작동 방식을 정확히 확인하는 것이 가장 좋습니다. 마찬가지로 조건부 연산자 (? :)는 적절한 ‘반'(값이 true이면 왼쪽 절반, false이면 오른쪽 절반) 만 평가하여 다음과 같은 표현식을 사용할 수 있습니다.

int x = (y == null) ? 0 : y.getFoo();

NullPointerException이 없습니다.


답변

아니오, a가 ( or시험에서) 참이면 b의 값이 무엇이든 시험 결과가 항상 참이므로 b는 시험되지 않습니다.

간단한 테스트를 수행하십시오.

if (true || ((String) null).equals("foobar")) {
    ...
}

것입니다 하지 을 던져 NullPointerException!


답변

여기서 단락은 두 번째 조건이 평가되지 않음을 의미합니다.

A가 False이면 (A && B)가 단락됩니다.

A가 True 이면 (A && B)가 단락 되지 않습니다 .

(A || B)이면 A가 True 인 경우 단락됩니다.

만약 (A || B) A가 False 단락 되지 않습니다 .


답변

아닙니다. Java는 결과를 알면 단락되고 평가를 중단합니다.