Java运算符优先级指南

时间:2010-01-26 05:42:46

标签: java operators operator-precedence

误解 Java运算符优先级是常见问题和细微错误的来源。我很有兴趣了解即使是Java Language Specification也说,“建议代码不要严格依赖于此规范。” JLS §15.7首选明确 聪明,此领域是否有任何有用的指导原则?

以下是有关该主题的一些资源:

欢迎加入或更正。

6 个答案:

答案 0 :(得分:20)

就“真实世界”而言,可能公平地说:

  • 足够的程序员知道乘法/除法优先于加法/减法,在数学上是常规
  • 几乎没有任何程序员能记住任何其他优先规则

因此,除了*/ vs +-的特定情况之外,我实际上只是使用括号来明确定义预期的优先级。

答案 1 :(得分:5)

另一个相关的错误来源是如何累积舍入错误。这不是运算符优先顺序问题本身,而是在以算术等效方式重新排列操作数后获得不同结果时的惊喜源。这是David Goldberg的What Every Computer Scientist Should Know About Floating-Point Arithmetic的sun.com版本。

答案 2 :(得分:4)

引用(来自Java Language Specification §15.7)应在Evaluation Order的上下文中阅读。正如here所述,该部分涉及评估顺序,它与运营商优先级(或关联性)无关。

优先级和关联性会影响表达式树的 结构 (即哪些运算符作用于哪些操作数),而“评估顺序”仅影响表达式的顺序在计算表达式时,树 遍历 。评估顺序(或“遍历顺序”)没有任何影响,除非某些子表达式具有影响其他子表达式的结果(或副作用)的副作用。

例如,如果最初x == 1,则表达式++x/++x将评估为2/3(其计算结果为0),因为Java具有从左到右的评估顺序。如果Java中的评估顺序是从右向左,则在评估分子之前x将增加两次,并且表达式将评估为3/2(其计算结果为1)。如果评估顺序未定义,则表达式可以评估这些结果中的任何一个。

有问题的引用及其背景......

  

Java编程语言保证了操作数   运算符似乎在特定的评估顺序中进行评估,   即,从左到右。

     

建议代码不要严格依赖此规范。   当每个表达式最多包含一侧时,代码通常更清晰   效果,作为其最外层的操作

...不鼓励读者依赖于Java的评估顺序的左撇子(如上例所示)。它不会鼓励不必要的括号。

编辑:资源:Java operator precedence table,它还作为JLS各部分的索引,包含从中推断出每个优先级的语法语法。

答案 3 :(得分:2)

另外,不要忘记逻辑&&和||是快捷操作符,避免类似:

sideeffect1() || sideeffect2()

如果sideeffect1()的计算结果为true,则不会执行sideeffect2()。同样适用于&&和假。这与优先权并不完全相关,但在这些极端情况下, assiociativity 也可能是一个重要的方面,通常是无关紧要的(至少就我而言)

答案 4 :(得分:2)

JLS没有给出显式的运算符优先级表; JLS描述各种运营商时暗示了这一点。例如,ShiftExpression的语法是:

ShiftExpression:
    AdditiveExpression
    ShiftExpression << AdditiveExpression
    ShiftExpression >> AdditiveExpression
    ShiftExpression >>> AdditiveExpression

这意味着加法运算符(+-)的优先级高于左关联移位运算符(<<>>>>> )。

答案 5 :(得分:1)

在我看来,事实是“大多数程序员”认为“大多数其他程序员”不知道或不记得运算符优先级,所以他们沉迷于被称为'防御性编程'的'插入缺少的括号',只是为了'澄清'那个。是否记住这个三年级的东西是一个真正的问题是另一个问题。可以说,所有这些都是完全浪费时间,如果有什么事情让事情变得更糟。我自己的观点是,尽可能避免使用冗余语法,并且计算机程序员应该知道他们编程的语言,也可能提高他们对同事的期望。