为什么 Java 没有条件和以及条件或运算符的复合赋值版本?(&&=, ||=)

因此,对于布尔值上的二元运算符,Java 具有 、 、 和 。&|^&&||

让我们在这里简要总结一下他们做了什么:

对于 ,则结果值为如果两个操作数值都为 ;否则,结果为 。&truetruefalse

对于 ,则结果值为如果两个操作数值都为 ;否则,结果为 。|falsefalsetrue

对于 ,结果值是如果操作数值不同;否则,结果为 。^truefalse

运算符类似于,但仅当其左侧操作数的值为 时,才计算其右侧操作数。&&&true

运算符类似于 ,但仅当其左侧操作数的值为 时,才计算其右侧操作数。|||false

现在,在所有 5 个中,其中 3 个具有复合赋值版本,即 和 。所以我的问题很明显:为什么Java没有提供和呢?我发现我需要的比我需要的更多。|=&=^=&&=||=&=|=

我不认为“因为它太长了”是一个很好的答案,因为Java有.这种遗漏必须有更好的理由。>>>=


15.26 赋值运算符:

有12个赋值运算符;[...]= *= /= %= += -= <<= >>= >>>= &= ^= |=


有人评论说,如果 和 被实现,那么将是唯一不首先评估右侧的运算符。我认为复合赋值运算符首先评估右侧的概念是错误的。&&=||=

15.26.2 复合赋值运算符开始

该形式的复合赋值表达式等价于 ,其中 是 的类型,只计算一次。E1 op= E2E1 = (T)((E1) op (E2))TE1E1

作为证明,以下代码段抛出一个 ,而不是一个 .NullPointerExceptionArrayIndexOutOfBoundsException

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

答案 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() 返回值如何,它总是被调用。这就像只有当返回时才调用where。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 ...

答案 2

可能是因为像这样的东西

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

看起来它应该赋值和计算,但是从语法中看不出评估值取决于 的值。xsomeComplexExpression()x

还因为Java的语法是基于C的,没有人认为迫切需要添加这些运算符。无论如何,使用if语句可能会更好。


推荐