所以对于 boolean 值的二元运算符,Java 有 &
, |
, ^
, &&
和 ||
.
让我们在这里简要总结一下他们做了什么:
- JLS 15.22.2 Boolean Logical Operators &, ^, and |
- JLS 15.23 Conditional-And Operator &&
- JLS 15.24 Conditional-Or Operator ||
For
&
, the result value istrue
if both operand values aretrue
; otherwise, the result isfalse
.For
|
, the result value isfalse
if both operand values arefalse
; otherwise, the result istrue
.For
^
, the result value istrue
if the operand values are different; otherwise, the result isfalse
.The
&&
operator is like&
but evaluates its right-hand operand only if the value of its left-hand operand istrue
.The
||
operator is like|
, but evaluates its right-hand operand only if the value of its left-hand operand isfalse
.
现在,在所有 5 个中,其中 3 个具有复合赋值版本,即 |=
, &=
和 ^=
.所以我的问题很明显:为什么 Java 不提供 &&=
和 ||=
也?我发现我需要的比我需要的多&=
和 |=
.
而且我不认为“因为它太长”是一个好的答案,因为 Java 有 >>>=
.这种遗漏一定有更好的理由。
来自 15.26 Assignment Operators :
There are 12 assignment operators; [...]
= *= /= %= += -= <<= >>= >>>= &= ^= |=
有一条评论指出,如果 &&=
和 ||=
被实现,那么它将是唯一不首先评估右手边的运算符。我认为复合赋值运算符首先计算右手边的想法是错误的。
来自 15.26.2 Compound Assignment Operators :
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
.
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();
只有在 f1()
返回 时才调用
。 f2()
真
如果开发者希望 f2()
仅在 f1()
返回 true
时调用,那么上面的第二个代码错误较少-容易。
否则 &=
就足够了,因为开发人员希望始终调用 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
比较 &&
和 &
结果
运算符 &&
和 &
应用于 boolean 值时的结果是否相同?
让我们使用以下 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 我们可以将 &&
替换为 &
以获得 boolean 值 ;-)
所以最好使用 &=
而不是 &&=
。
||=
相同
与 &&=
的原因相同:
运算符 |=
比 ||=
更不容易出错。
如果开发人员希望 f1()
返回 true
时不调用 f2()
,那么我建议以下替代方案:
// 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 - 为什么 Java 没有条件与和条件或运算符的复合赋值版本? (&&=, ||=),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2324549/