代码之家  ›  专栏  ›  技术社区  ›  polygenelubricants

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

  •  74
  • polygenelubricants  · 技术社区  · 15 年前

    & , | , ^ , && || .

    让我们简要总结一下他们的工作:

    为了 & ,结果值为 true 如果两个操作数值都是 是的 ;否则,结果是 false .

    | ,结果值为 如果两个操作数值都是 ;否则,结果是 是的

    为了 ^ ,结果值为 是的 如果操作数值不同,则返回结果

    这个 && 接线员就像 & 是的 .

    这个 接线员就像 |

    现在,在这5个版本中,有3个有复合赋值版本,即 |= , &= ^= &&= ||= 也?我发现我比我需要的更多 & |=

    我不认为“因为它太长了”是个好答案,因为Java >>>= . 这种疏漏肯定有更好的理由。


    15.26 Assignment Operators :

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


    有人评论说,如果 && ||=

    15.26.2 Compound Assignment Operators

    形式的复合赋值表达式 E1 op= E2 E1 = (T)((E1) op (E2)) T 是类型 E1 ,除了 E1级

    作为证明,下面的代码片段抛出 NullPointerException ArrayIndexOutOfBoundsException .

        int[] a = null;
        int[] b = {};
        a[0] += b[-1];
    
    11 回复  |  直到 15 年前
        1
  •  28
  •   oHo Denis Tulskiy    8 年前

    原因

    &&= ||= 在上不可用 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
    

    第一个代码是 易出错 f2() 总是调用f1()返回的值。就像 bool isOk = 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
    

    比较 && & 结果

    是运算符的结果 && &

    让我们使用以下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
    ======================
    

    因此 && 通过 & 对于布尔值;-)

    &= &&= .

    与…相同的理由 &&= :
    |= 不易出错 .

    如果开发者想要 f2() 什么时候不打电话 f1() 退货 是的

    // 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
  •  17
  •   Josh Lee ZZ Coder    15 年前

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

    x 评估 someComplexExpression() 但事实上,评估取决于 从语法上看不明显。

    另外,因为Java的语法是基于C的,没有人认为迫切需要添加这些操作符。不管怎样,用if语句可能会更好。

        3
  •  12
  •   EFraim    16 年前

    在Java中是这样的,因为在C中是这样的。

    现在的问题是,为什么在C中如此,是因为当&和&成为不同的运算符时(在C从B下降之前的某个时间),运算符的种类被简单地忽略了。

        4
  •  6
  •   p00ya    15 年前

    很大程度上是因为Java语法基于C(或者至少是C族),而在C中,所有这些赋值运算符都被编译成单个寄存器上的算术或按位汇编指令。赋值运算符版本避免了临时性,并且可能在早期的非优化编译器上生成了更高效的代码。逻辑运算符(在C中称为)的等价形式( &&= ||= )与单个汇编指令没有如此明显的对应关系;它们通常扩展到测试和分支指令序列。

    有| |=和&=。

    编辑:Java和C的术语不同

        5
  •  4
  •   Yishai    16 年前

    Java的原版之一 aims 是“简单的,面向对象的,熟悉的”。应用于这种情况下,& & =是熟悉的(C,C++有它,熟悉在这方面意味着熟悉的人谁知道这两个)。

    &&=不会很熟悉,也不会很简单,因为语言设计者并没有考虑他们可以添加到语言中的每一个操作符,所以额外的操作符越少就越简单。

        6
  •  3
  •   zanfilip    12 年前

    而不是写作

    foreach(item in coll)
    {
       bVal = bVal || fn(item); // not so elegant
    }
    

    foreach(item in coll)
    {
      bVal ||= fn(item);    // elegant
    }
    

        7
  •  2
  •   NawaMan    16 年前

    & '和' && && '是一个快捷操作,当' &

    我确实同意存在更有意义,但如果不存在也没那么糟糕。我想它不在那里是因为C没有它。

    真想不出为什么。

        8
  •  0
  •   zzawaideh    16 年前

    如果我猜的话,我会说它不经常使用,所以没有实现。另一种解释可能是解析器只查看=

        9
  •  0
  •   Daniel Brückner    16 年前

    我想不出比这更好的理由了,那就是“它看起来非常丑陋!”

        10
  •  0
  •   Ely    10 年前

    &

    &&

    如果第一个操作数的计算结果为false,则停止计算,因为结果将为false,这是一个逻辑运算符。它可以应用于布尔函数。

    运算符与运算符类似,但可以提高代码的效率。因为由&运算符比较的两个表达式都必须是betrue,才能使整个表达式为betrue,所以如果第一个表达式返回false,则没有理由对第二个表达式求值。运算符始终计算这两个表达式。运算符仅当第一个表达式为真时才计算第二个表达式。

    拥有一个&=assignment操作符并不能真正为语言添加新的功能。位运算符的算法更具表现力,可以做整数位运算,其中包括布尔运算。逻辑运算符只能做布尔运算。

        11
  •  0
  •   Marcono1234    5 年前

    Brian Goetz(Oracle的Java语言架构师) wrote :

    表明有兴趣拥有这些运算符,并且 因此,问题是:JDK团队过去是否讨论过添加这些操作符,如果是这样的话

    我不知道关于这个问题有什么具体的讨论,但是 如果有人提议,答案很可能是:这不是一个好主意 不合理的要求,但却不值一提。

    “承载它的重量”需要根据它的成本和收益来判断,以及 相对于其他候选特征的成本效益比。

    成本接近于零,收益大于零,所以 似乎是个明显的胜利。但这掩盖了对这个问题的错误理解 这样的特性会影响语言规范和实现, JCK,以及所有的IDE和Java教科书。没有琐碎的语言 特征。虽然收益不为零,但也很小。

    第二,我们有无限多的特征 能够 是的,但是我们 只有能力每隔几年做一小部分(而且用户有 至于我们选择哪一个,作为每一个特征(即使是看似微不足道的特征)
    不是“为什么不使用此功能”,而是“我们还将不使用哪些其他功能?” (或推迟)这样我们就可以做这件事了,这是笔好买卖吗?”我呢 正在工作。

    因此,它清除了“不是一个可怕的想法”的障碍(这已经很好了) 不太可能清除“更好地利用我们的预算”的障碍 “比什么都重要。”

        12
  •  -1
  •   Omry Yadan    16 年前

    a&b和a&b不是一回事。

    a&b是返回布尔值的布尔表达式,a&b是返回int的位表达式(如果a和b是int)。

    你认为他们是什么样的人?

    推荐文章