误解 Java运算符优先级是常见问题和细微错误的来源。我很有兴趣了解即使是Java Language Specification也说,“建议代码不要严格依赖于此规范。” JLS §15.7首选明确 聪明,此领域是否有任何有用的指导原则?
以下是有关该主题的一些资源:
欢迎加入或更正。
答案 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)
在我看来,事实是“大多数程序员”认为“大多数其他程序员”不知道或不记得运算符优先级,所以他们沉迷于被称为'防御性编程'的'插入缺少的括号',只是为了'澄清'那个。是否记住这个三年级的东西是一个真正的问题是另一个问题。可以说,所有这些都是完全浪费时间,如果有什么事情让事情变得更糟。我自己的观点是,尽可能避免使用冗余语法,并且计算机程序员应该知道他们编程的语言,也可能提高他们对同事的期望。