Java 运算符优先级指南

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2137690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:38:09  来源:igfitidea点击:

Java operator precedence guidelines

javaoperatorsoperator-precedence

提问by trashgod

Misunderstanding Java operator precedenceis a source of frequently asked questions and subtle errors. I was intrigued to learn that even the Java Language Specificationsays, "It is recommended that code not rely crucially on this specification." JLS §15.7Preferring clearto clever, are there any useful guidelines in this area?

Java 运算符优先级的误解是常见问题和细微错误的来源。我很感兴趣地了解到,即使Java 语言规范也说:“建议代码不要过分依赖此规范。” JLS§15.7宁愿明确聪明,有没有这方面的任何有用的指导?

Here are a number of resources on the topic:

以下是有关该主题的许多资源:

Additions or corrections welcome.

欢迎补充或更正。

回答by Neil Coffey

As far as the "Real World" is concerned, it's probably fair to say:

就“真实世界”而言,可以这么说:

  • enough programmers know that multiplication/division take precedence over addition/subtraction, as is mathematically the convention
  • hardly any programmers can remember any of the other rules of precedence
  • 足够多的程序员知道乘法/除法优先于加法/减法,这是数学上的约定
  • 几乎没有程序员能记住任何其他优先规则

So, apart from the specific case of */vs +-, I'd really just use brackets to explicitly define the precedence intended.

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

回答by iter

Another related source of bugs is how rounding errors accumulate. Not an operator precedence order issue per se, but a source of surprise when you get a different result after rearranging operands in an arithmetically-equivalent way. Here's a sun.com version of David Goldberg's What Every Computer Scientist Should Know About Floating-Point Arithmetic.

另一个相关的错误来源是舍入错误如何累积。本身不是运算符优先顺序问题,而是在以算术等效的方式重新排列操作数后得到不同结果时的意外来源。这是 David Goldberg 的 Sun.com 版本的每个计算机科学家应该知道的关于浮点运算的知识

回答by Museful

The quote (from the Java Language Specification §15.7) should be read in the context of Evaluation Order. As discussed here, that section concerns evaluation order, which is not related to operator precedence(or associativity).

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

Precedence and associativity influence the structureof the expression tree (i.e. which operators act on which operands), while "evaluation order" merely influences the order in which the expression tree is traversedwhen the expression is evaluated. Evaluation order (or "traversal order") does not have any effect unless some sub-expressions have side-effects that affect the result (or side-effects) of other sub-expressions.

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

For example, if x==1 initially, the expression ++x/++xwould evaluate as 2/3 (which evaluates to 0) since Java has left-to-right evaluation order. Had evaluation order in Java been right-to-left, x would have been incremented twice before the numerator is evaluated, and the expression would have evaluated as 3/2 (which evaluates to 1). Had evaluation order been undefined, the expression could have evaluated to either of these results.

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

The quote in question, together with its context, ...

有问题的引用及其上下文,......

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

It is recommended that code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect, as its outermost operation

Java 编程语言保证运算符的操作数以特定的求值顺序进行求值,即从左到右。

建议代码不要过分依赖此规范。当每个表达式最多包含一个副作用时,代码通常会更清晰,因为它的最外层操作

...discourages the reader from depending on the left-to-rightness of Java's evaluation order(as in the example above). It does not encourage unnecessary parentheses.

...不鼓励读者依赖 Java 计算顺序的从左到右(如上例所示)。它不鼓励不必要的括号。

Edit: Resource: Java operator precedence tablethat also serves as an index into sections of the JLS containing the syntactic grammar from which each precedence level is inferred.

编辑:资源:Java 运算符优先级表,它也用作 JLS 部分的索引,其中包含推断每个优先级级别的句法语法。

回答by kutschkem

Also, don't forget the logical && and || are shortcut operators, avoid something like:

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

sideeffect1() || sideeffect2()

If sideeffect1() is evaluating to true, sideeffect2() isn't going to be executed. The same goes for && and false. This is not entirely related to precendence, but in these extreme cases the assiociativitycan also be an important aspect that normally is really irrelevant (at least as far as i am concerned)

如果 sideeffect1() 的计算结果为 true,则 sideeffect2() 不会被执行。&& 和 false 也是如此。这并不完全与precendence,但在这些极端情况下assiociativity也可以是一个重要的方面,通常是真的无关紧要的(至少就我而言)

回答by Jingguo Yao

The JLSdoes not give an explicit operator precedence table; it is implied when the JLSdescribes various operators. For example, the grammar for ShiftExpressionis this:

JLS没有给出一个明确的运算符优先级表; 当JLS描述各种运算符时,它是隐含的。例如,for 的语法ShiftExpression是这样的:

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

This means that additive operators (+and -) have a higher precedence than the left-associative shift operators (<<, >>and >>>).

这意味着加法运算符 ( +and -) 比左关联移位运算符 ( <<,>>>>>)具有更高的优先级。

回答by user207421

It seems to me that the truth of this is that 'most programmers' think 'most other programmers' don't know or can't remember operator precedence, so they indulge in what is indulgently called 'defensive programming' by 'inserting the missing parentheses', just to 'clarify' that. Whether remembering this third-grade stuff is a real problem is another question. It just as arguable that all this is a complete waste of time and if anything makes things worse. My own view is that redundant syntax is to be avoided wherever possible, and that computer programmers should know the language they are programming in, and also perhaps raise their expectations of their colleagues.

在我看来,事实的真相是“大多数程序员”认为“大多数其他程序员”不知道或不记得运算符优先级,因此他们沉迷于通过“插入缺失的括号”,只是为了“澄清”这一点。记住这个三年级的东西是否是一个真正的问题是另一个问题。同样有争议的是,这一切完全是在浪费时间,如果有什么事情会让事情变得更糟的话。我个人的观点是,尽可能避免冗余语法,计算机程序员应该知道他们正在编程的语言,并且也许还可以提高他们对同事的期望。