그래서 논리 값이 이진 사업자, 자바가 &
, |
, ^
, &&
와 ||
.
여기에서 그들이하는 일을 간단히 요약 해 보겠습니다.
의 경우
&
결과 값은true
두 피연산자 값이 모두 다음 과 같은 경우입니다true
. 그렇지 않으면 결과는false
입니다.의 경우
|
결과 값은false
두 피연산자 값이 모두 다음 과 같은 경우입니다false
. 그렇지 않으면 결과는true
입니다.의 경우
^
결과 값은true
피연산자 값이 다른 경우입니다. 그렇지 않으면 결과는false
입니다.
&&
연산자 비슷&
하지만 좌측의 값이 피연산자는 우측 피연산자 만 평가한다true
.
||
연산자 비슷|
하지만, 그 좌측의 값이 피연산자는 우측 피연산자 만 평가한다false
.
자, 모두 5 중, 그 중 3, 즉 화합물 할당 버전을 가지고 |=
, &=
하고 ^=
. 내 질문은 분명하다 그래서 왜 자바는 제공하지 않습니다 &&=
및 ||=
뿐만 아니라? 나는 그보다 내가 필요한 것보다 필요한 것을 발견 &=
하고 |=
.
그리고 Java가 .NET을 가지고 있기 때문에 “너무 길기 때문에”가 좋은 대답이라고 생각하지 않습니다 >>>=
. 이 누락에 대한 더 나은 이유가있을 것입니다.
15.26 할당 연산자 부터 :
12 개의 할당 연산자가 있습니다. […]
= *= /= %= += -= <<= >>= >>>= &= ^= |=
&&=
및 ||=
구현 된 경우 오른쪽을 먼저 평가하지 않는 유일한 연산자라는 의견이 작성 되었습니다. 복합 할당 연산자가 오른쪽을 먼저 평가한다는이 개념은 실수라고 생각합니다.
가입일 15.26.2 화합물 할당 연산자 :
형태의 복합 대입 식을
E1 op= E2
동등E1 = (T)((E1) op (E2))
여기서T
의 타입E1
즉 제외E1
한번만 평가된다.
증거로 다음 스 니펫 NullPointerException
은 ArrayIndexOutOfBoundsException
.
int[] a = null;
int[] b = {};
a[0] += b[-1];
답변
이유
대부분의 개발자에게 이러한 연산자는 다음과 같기 때문에 연산자 &&=
및 Java||=
에서는 사용할 수 없습니다 .
- 발생하기 쉬운 오류
- 쓸모없는
예 &&=
Java가 &&=
연산자를 허용하면 해당 코드는 다음과 같습니다.
bool isOk = true; //becomes false when at least a function returns false
isOK &&= f1();
isOK &&= f2(); //we may expect f2() is called whatever the f1() returned value
다음과 동일합니다.
bool isOk = true;
if (isOK) isOk = f1();
if (isOK) isOk = f2(); //f2() is called only when f1() returns true
이 첫 번째 코드는 많은 개발자 가 항상 f1 () 반환 값이 무엇이든 호출 된다고 생각 하기 때문에 오류가 발생 하기 쉽습니다f2()
. 반환 할 때만 호출 bool isOk = f1() && f2();
되는 곳 과 같습니다 .f2()
f1()
true
개발자가 f2()
를 f1()
반환 할 때만 호출 되기를 원하는 경우 true
위의 두 번째 코드는 오류가 덜 발생합니다.
Else &=
는 개발자가 f2()
항상 호출 되기를 원하기 때문에 충분합니다 .
같은 예이지만 &=
bool isOk = true;
isOK &= f1();
isOK &= f2(); //f2() always called whatever the f1() returned value
또한 JVM은 위의 코드를 다음과 같이 실행해야합니다.
bool isOk = true;
if (!f1()) isOk = false;
if (!f2()) isOk = false; //f2() always called
비교 &&
및 &
결과
연산자의 결과인가 &&
및 &
부울 값을 적용 할 때 같은?
다음 Java 코드를 사용하여 확인해 보겠습니다.
public class qalcdo {
public static void main (String[] args) {
test (true, true);
test (true, false);
test (false, false);
test (false, true);
}
private static void test (boolean a, boolean b) {
System.out.println (counter++ + ") a=" + a + " and b=" + b);
System.out.println ("a && b = " + (a && b));
System.out.println ("a & b = " + (a & b));
System.out.println ("======================");
}
private static int counter = 1;
}
산출:
1) a=true and b=true
a && b = true
a & b = true
======================
2) a=true and b=false
a && b = false
a & b = false
======================
3) a=false and b=false
a && b = false
a & b = false
======================
4) a=false and b=true
a && b = false
a & b = false
======================
따라서 YES 우리는 대체 할 수 있습니다 &&
에 의해 &
부울 값 😉
그래서 더 나은 사용하는 &=
대신 &&=
.
동일 ||=
와 같은 이유 &&=
:
연산자 |=
는 ||=
.
개발자가 반환 f2()
할 때 호출되지 않도록 하려면 다음 대안을 조언합니다.f1()
true
// here a comment is required to explain that
// f2() is not called when f1() returns false, and so on...
bool isOk = f1() || f2() || f3() || f4();
또는:
// here the following comments are not required
// (the code is enough understandable)
bool isOk = false;
if (!isOK) isOk = f1();
if (!isOK) isOk = f2(); //f2() is not called when f1() returns false
if (!isOK) isOk = f3(); //f3() is not called when f1() or f2() return false
if (!isOK) isOk = f4(); //f4() is not called when ...
답변
아마도 뭔가
x = false;
x &&= someComplexExpression();
에 할당 x
하고 평가 해야하는 것처럼 보이지만someComplexExpression()
평가가의 값에 달려 있다는 사실 x
은 구문에서 명확하지 않습니다.
또한 Java의 구문은 C를 기반으로하기 때문에 아무도 이러한 연산자를 추가해야하는 절박한 필요성을 느끼지 못했습니다. 어쨌든 if 문을 사용하는 것이 더 나을 것입니다.
답변
Java에서는 이런 방식입니다. C에서는 이런 방식이기 때문입니다.
이제 C에서 왜 그렇게 되는가에 대한 질문은 &와 &&가 다른 연산자가되었을 때 (때로는 B에서 C의 하강 이전에) & = 다양한 연산자를 간과했기 때문입니다.
그러나 내 대답의 두 번째 부분에는이를 뒷받침 할 출처가 없습니다.
답변
Java 구문은 C (또는 적어도 C 계열)를 기반으로하고 C에서 이러한 모든 할당 연산자는 단일 레지스터의 산술 또는 비트 어셈블리 명령어로 컴파일되기 때문입니다. 할당 연산자 버전은 임시를 피하고 초기 비 최적화 컴파일러에서 더 효율적인 코드를 생성했을 수 있습니다. 논리 연산자 (C로 표시됨) 등가물 ( &&=
및 ||=
)은 단일 어셈블리 명령에 대한 명백한 대응이 없습니다. 일반적으로 테스트 및 분기 명령 시퀀스로 확장됩니다.
흥미롭게도, 루비 같은 언어는 않습니다 및 && = || 있습니다.
편집 : Java와 C의 용어가 다릅니다.
답변
Java의 원래 목표 중 하나는 “단순하고 객체 지향적이며 친숙한”것이 었습니다. 이 경우에 적용하면 & =는 익숙합니다 (C, C ++는이 두 가지를 알고있는 사람에게 친숙 함을 의미하며이 컨텍스트에서 익숙 함을 의미합니다).
&& =는 익숙하지 않을 것이며, 언어 설계자들이 언어에 추가 할 수있는 모든 연산자를 생각하지 않기 때문에 간단하지 않을 것입니다. 따라서 추가 연산자가 덜 간단합니다.
답변
부울 변수의 경우 && 및 || & 및 | 동안 단락 평가를 사용합니다. 그렇지 않으면 && = 및 || =도 단락 평가를 사용할 것으로 예상됩니다. 이에 대한 좋은 사용 사례가 있습니다. 특히 루프를 반복하는 경우 빠르고 효율적이며 간결해야합니다.
쓰는 대신
foreach(item in coll)
{
bVal = bVal || fn(item); // not so elegant
}
나는 쓰고 싶다
foreach(item in coll)
{
bVal ||= fn(item); // elegant
}
bVal이 참이면 나머지 반복에 대해 fn ()이 호출되지 않습니다.
답변
‘ &
‘와 ‘ &&
‘는 같지 않습니다. ‘ &&
‘는 첫 번째 피연산자가 거짓이면 수행하지 않는 바로 가기 연산이며 ‘ &
‘는 어쨌든 수행합니다 (숫자 및 부울 모두에서 작동).
나는 존재하는 것이 더 합리적이라는 데 동의하지만 그것이 존재하지 않아도 그렇게 나쁘지는 않습니다. C가 가지고 있지 않기 때문에 거기에 없었던 것 같아요.
정말 이유를 생각할 수 없습니다.