program story

Java에 조건부 및 조건부 또는 연산자의 복합 할당 버전이없는 이유는 무엇입니까?

inputbox 2020. 10. 15. 07:45
반응형

Java에 조건부 및 조건부 또는 연산자의 복합 할당 버전이없는 이유는 무엇입니까? (&& =, || =)


그래서 논리 값이 이진 사업자, 자바가 &, |, ^, &&||.

여기서 그들이하는 일을 간단히 요약 해 보겠습니다.

의 경우 &결과 값은 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한번만 평가된다.

증거로 다음 스 니펫 NullPointerExceptionArrayIndexOutOfBoundsException.

    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은 구문에서 명확하지 않습니다.

Also because Java's syntax is based on C, and no one saw a pressing need to add those operators. You'd probably be better off with an if statement, anyway.


It is this way in Java, because it is this way in C.

Now the question why it is so in C is because when & and && became different operators (sometime preceding C's descent from B), the &= variety of operators was simply overlooked.

But the second part of my answer does not have any sources to back it up.


One of Java's original aims was to be "Simple, Object Oriented, and Familiar." As applied to this case, &= is familiar (C, C++ have it and familiar in this context meant familiar to someone who knows those two).

&&= would not be familiar, and it would not be simple, in the sense that the language designers were not looking to think of every operator they could add to the language, so less extra operators are simpler.


Largely because Java syntax is based on C (or at least the C family), and in C all those assignment operators get compiled to arithmetic or bitwise assembly instructions on a single register. The assignment-operator version avoids temporaries and may have produced more efficient code on early non-optimising compilers. The logical operator (as they are termed in C) equivalents (&&= and ||=) don't have such an obvious correspondence to single assembly instructions; they usually expand to a test and branch sequence of instructions.

Interestingly, languages like ruby do have ||= and &&=.

Edit: terminology differs between Java and C


For Boolean vars, && and || would use short circuit evaluation while & and | don't, so you would expect &&= and ||= to also use short circuit evaluation. There is a good use case for this. Especially if you are iterating over a loop, you want to be fast, efficient and terse.

Instead of writing

foreach(item in coll)
{
   bVal = bVal || fn(item); // not so elegant
}

I want to write

foreach(item in coll)
{
  bVal ||= fn(item);    // elegant
}

and know that once bVal is true, fn() will not be called for the remainder of the iterations.


'&' and '&&' are not the same as '&&' is a short cut operation which will not do if the first operand is false while '&' will do it anyway (works with both number and boolean).

I do agree that it make more sense to exist but it is not that bad if it is not there. I guess it was not there because C does not have it.

Really can't think of why.


It is allowed in Ruby.

If I were to guess, I would say that it is not frequently used so it wasn't implemented. Another explanation could be that the parser only looks at the character before the =


I cannot think of any better reason then 'It looks incredible ugly!'


&

verifies both operands, it's a bitwise operator. Java defines several bitwise operators, which can be applied to the integer types, long, int, short, char, and byte.

&&

stops evaluating if the first operand evaluates to false since the result will be false, it's a logical operator. It can be applied to booleans.

The && operator is similar to the  & operator, but can make your code a bit more efficient. Because both expressions compared by the & operator must be true for the entire expression to be true, there’s no reason to evaluate the second expression if the first one returns false. The & operator always evaluates both expressions. The && operator evaluates the second expression only if the first expression is true.

Having a &&= assignment operator wouldn't really add new functionality to the language. The bitwise operator's arithmetic is much more expressive, you can do integer bitwise arithmetic, which includes Boolean arithmetic. The logical operators can merely do Boolean arithmetic.


a&b and a && b are not the same thing.

a && b is a boolean expression that returns a boolean, and a & b is a bitwise expression that returns an int (if a and b are ints).

whare do you think they are the same?

참고URL : https://stackoverflow.com/questions/2324549/why-doesnt-java-have-compound-assignment-versions-of-the-conditional-and-and-co

반응형