为什么 Java 没有条件和和条件或运算符的复合赋值版本?(&&=, ||=) [英] Why doesn't Java have compound assignment versions of the conditional-and and conditional-or operators? (&&=, ||=)
问题描述
所以对于布尔值的二元运算符,Java 有 &
、|
、^
、&&
和 ||
.
So for binary operators on booleans, Java has &
, |
, ^
, &&
and ||
.
让我们在这里简要总结一下他们的工作:
Let's summarize what they do briefly here:
对于&
,如果两个操作数的值为true
,则结果值为true
;否则,结果为false
.
For
&
, the result value istrue
if both operand values aretrue
; otherwise, the result isfalse
.
对于|
,如果两个操作数的值为false
,则结果值为false
;否则,结果为 true
.
For |
, the result value is false
if both operand values are false
; otherwise, the result is true
.
对于^
,如果操作数不同,结果值为true
;否则,结果为false
.
For ^
, the result value is true
if the operand values are different; otherwise, the result is false
.
&&
运算符与 &
类似,但仅当其左手操作数的值为 true<时才计算其右手操作数代码>.
The &&
operator is like &
but evaluates its right-hand operand only if the value of its left-hand operand is true
.
||
运算符类似于 |
,但仅当其左手操作数的值为 false
时才计算其右手操作数>.
The ||
operator is like |
, but evaluates its right-hand operand only if the value of its left-hand operand is false
.
现在,在所有 5 个中,其中 3 个具有复合赋值版本,即 |=
、&=
和 ^=
.所以我的问题很明显:为什么 Java 不提供 &&=
和 ||=
?我发现我需要这些比 &=
和 |=
更需要.
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 |=
.
而且我不认为因为它太长"是一个好的答案,因为 Java 有 >>>=
.这种遗漏一定有更好的理由.
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.
来自 15.26 赋值运算符:
有12个赋值运算符;[...] = *=/= %= += -= <<= >>= >>>= &= ^= |=
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.
来自 15.26.2 复合赋值运算符:
E1 op= E2
形式的复合赋值表达式等价于 E1 = (T)((E1) op (E2))
,其中 T
是 E1
的类型,除了 E1
只计算一次.
A compound assignment expression of the form
E1 op= E2
is equivalent toE1 = (T)((E1) op (E2))
, whereT
is the type ofE1
, except thatE1
is evaluated only once.
作为证据,以下代码段抛出了一个 NullPointerException
,而不是一个 ArrayIndexOutOfBoundsException
.
As proof, the following snippet throws a NullPointerException
, not an ArrayIndexOutOfBoundsException
.
int[] a = null;
int[] b = {};
a[0] += b[-1];
推荐答案
原因
运算符 &&=
和 ||=
在 Java 上不可用,因为对于大多数开发人员来说,这些运算符是:
Reason
The operators &&=
and ||=
are not available on Java because for most of the developers these operators are:
- 容易出错
- 没用
如果 Java 允许 &&=
运算符,则该代码:
If Java allowed &&=
operator, then that code:
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
时调用.
This first code is error-prone because many developers would think f2()
is always called whatever the f1() returned value. It is like bool isOk = f1() && f2();
where f2()
is called only when f1()
returns true
.
如果开发者希望 f2()
只在 f1()
返回 true
时被调用,那么上面的第二个代码错误较少-倾向.
If the developer wants f2()
to be called only when f1()
returns true
, therefore the second code above is less error-prone.
Else &=
就足够了,因为开发人员希望 f2()
总是被调用:
Else &=
is sufficient because the developer wants f2()
to be always called:
bool isOk = true;
isOK &= f1();
isOK &= f2(); //f2() always called whatever the f1() returned value
此外,JVM 应该按照以下代码运行上面的代码:
Moreover, the JVM should run this above code as the following one:
bool isOk = true;
if (!f1()) isOk = false;
if (!f2()) isOk = false; //f2() always called
比较&&
和&
结果
运算符 &&
和 &
应用于布尔值时的结果是否相同?
Compare &&
and &
results
Are the results of operators &&
and &
the same when applied on boolean values?
让我们使用以下 Java 代码进行检查:
Let's check using the following Java code:
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 我们可以将 &&
替换为 &
用于布尔值 ;-)
Therefore YES we can replace &&
by &
for boolean values ;-)
所以最好使用 &=
而不是 &&=
.
So better use &=
instead of &&=
.
与 &&=
的原因相同:
运算符 |=
比 ||=
更不容易出错.
Same reasons as for &&=
:
operator |=
is less error-prone than ||=
.
如果开发人员希望在 f1()
返回 true
时不调用 f2()
,那么我建议以下替代方案:
If a developer wants f2()
not to be called when f1()
returns true
, then I advice the following alternatives:
// 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 ...
这篇关于为什么 Java 没有条件和和条件或运算符的复合赋值版本?(&&=, ||=)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!