views:

384

answers:

2

So for binary operators on booleans, Java has &, |, ^, && and ||.

Let's summarize what they do briefly here:

For &, the result value is true if both operand values are true; otherwise, the result is false.

For |, the result value is false if both operand values are false; otherwise, the result is true.

For ^, the result value is true if the operand values are different; otherwise, the result is false.

The && operator is like & but evaluates its right-hand operand only if the value of its left-hand operand is true.

The || operator is like |, but evaluates its right-hand operand only if the value of its left-hand operand is false.

Now, among all 5, 3 of those have compound assignment versions, namely |=, &= and ^=. So my question is obvious: why doesn't Java provide &&= and ||= as well? I find that I need those more than I need &= and |=.

And I don't think that "because it's too long" is a good answer, because Java has >>>=. There must be a better reason for this omission.


From 15.26 Assignment Operators:

There are 12 assignment operators; [...] = *= /= %= += -= <<= >>= >>>= &= ^= |=


A comment was made that if &&= and ||= were implemented, then it would be the only operators that do not evaluate the right hand side first. I believe this notion that a compound assignment operator evaluates the right hand side first is a mistake.

From 15.26.2 Compound Assignment Operators:

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

As proof, the following snippet throws a NullPointerException, not an ArrayIndexOutOfBoundsException.

    int[] a = null;
    int[] b = {};
    a[0] += b[-1];
+1  A: 

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

p00ya
I believe you mean the **conditional** operator equivalents don't have such obvious correspondence. In JLS terminology, the boolean logical operators are `
polygenelubricants
In C terminology, there is no single-bit type in C and the logical operators there apply to all scalar types.
p00ya
+7  A: 

Probably because something like

x = false;
x &&= someComplexExpression();

looks like it ought to be assigning to x and evaluating someComplexExpression(), but the fact that the evaluation hinges on the value of x isn't apparent from the syntax.

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.

jleedev
polygenelubricants
PSpeed
@polygene That's fair. How something looks is based on what you're familiar with, though, and I guess they didn't want to add anything new. One thing I like about C/C++/Java/C# is that the basic syntax of expressions is nearly identical.
jleedev
@PSpeed, you are mistaken. The JLS is very clear on what the compound assignment is supposed to do. See my addition above.
polygenelubricants
I think saying that they aren't there because the designers simply followed the precedence set by C is misleading, since they did add `>>>` and `>>>=`, which are entirely new.
polygenelubricants
@PSpeed: In that case, `a -= b;` would work entirely differently from `a `.
David Thornley