pol*_*nts 77 java conditional-operator short-circuiting assignment-operator compound-assignment
因此,对于在布尔二元运算符,Java有&
,|
,^
,&&
和||
.
让我们简要总结一下他们在这里简要介绍的内容:
对于
&
,结果值是true
两个操作数值是否为true
; 否则,结果是false
.对于
|
,结果值是false
两个操作数值是否为false
; 否则,结果是true
.对于
^
,结果值是true
操作数值是否不同; 否则,结果是false
.该
&&
操作是一样&
,但是评估其右边的操作数只有在其左侧操作数的值true
.该
||
操作是一样|
的,但评估其右边的操作数只有在其左侧操作数的值false
.
现在,所有5间,那些3有复合赋值版本,分别为|=
,&=
和^=
.所以我的问题是显而易见的:为什么不是Java提供&&=
和||=
呢?我发现我需要那些比我更需要更多的&=
和|=
.
而且我不认为"因为它太长"是一个很好的答案,因为Java有>>>=
.这个遗漏必须有更好的理由.
有12个赋值运算符; [...]
= *= /= %= += -= <<= >>= >>>= &= ^= |=
有人评论说,如果&&=
并且||=
实施了,那么它将是唯一不首先评估右侧的运营商.我相信复合赋值运算符首先评估右侧的概念是错误的.
除了仅计算一次之外,表单的复合赋值表达式
E1 op= E2
等效于E1 = (T)((E1) op (E2))
,whereT
的类型.E1
E1
作为证据,以下片段引发了一个NullPointerException
,而不是一个ArrayIndexOutOfBoundsException
.
int[] a = null;
int[] b = {};
a[0] += b[-1];
Run Code Online (Sandbox Code Playgroud)
oli*_*bre 25
运营商&&=
和||=
不提供的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
Run Code Online (Sandbox Code Playgroud)
相当于:
bool isOk = true;
if (isOK) isOk = f1();
if (isOK) isOk = f2(); //f2() is called only when f1() returns true
Run Code Online (Sandbox Code Playgroud)
第一个代码容易出错,因为许多开发人员都认为f2()
无论f1()返回值是什么都会被调用.这就像bool isOk = f1() && f2();
在那里f2()
被称为只有当f1()
收益true
.
如果开发人员只想f2()
在f1()
返回时调用true
,那么上面的第二个代码不容易出错.
否则&=
就足够了,因为开发人员f2()
总是希望被称为:
&=
bool isOk = true;
isOK &= f1();
isOK &= f2(); //f2() always called whatever the f1() returned value
Run Code Online (Sandbox Code Playgroud)
此外,JVM应该运行以上代码,如下所示:
bool isOk = true;
if (!f1()) isOk = false;
if (!f2()) isOk = false; //f2() always called
Run Code Online (Sandbox Code Playgroud)
&&
和&
结果是运营商的结果&&
,并&
同当布尔值应用?
让我们使用以下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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
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
======================
Run Code Online (Sandbox Code Playgroud)
因此是我们可以更换&&
的&
布尔值;-)
所以更好地使用&=
而不是&&=
.
||=
原因相同&&=
:
运算符|=
比错误更少||=
.
如果开发人员想要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();
Run Code Online (Sandbox Code Playgroud)
要么:
// 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 ...
Run Code Online (Sandbox Code Playgroud)
Jos*_*Lee 16
可能是因为像
x = false;
x &&= someComplexExpression();
Run Code Online (Sandbox Code Playgroud)
看起来它应该分配x
和评估someComplexExpression()
,但评估取决于价值的事实x
在语法上并不明显.
另外因为Java的语法基于C语言,没有人看到迫切需要添加这些运算符.无论如何,你可能会更好地使用if语句.
这是Java中的这种方式,因为它在C语言中是这样的.
现在问题为什么它在C中是这样的,因为当&和&&成为不同的运算符(在C从C下降之前的某个时间),&=各种运算符被忽略了.
但我的答案的第二部分没有任何来源支持它.
主要是因为 Java 语法基于 C(或至少是 C 系列),并且在 C 中,所有这些赋值运算符都被编译为单个寄存器上的算术或按位汇编指令。赋值运算符版本避免了临时性,并且可能在早期的非优化编译器上生成了更高效的代码。逻辑运算符(在 C 中称为)等价物 ( &&=
and ||=
) 与单个汇编指令没有如此明显的对应关系;它们通常扩展为测试和分支指令序列。
有趣的是,像 ruby这样的语言确实有 ||= 和 &&=。
编辑:Java 和 C 之间的术语不同
归档时间: |
|
查看次数: |
13661 次 |
最近记录: |