Java中评估顺序的规则是什么? [英] What are the rules for evaluation order in Java?

查看:142
本文介绍了Java中评估顺序的规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读一些Java文本并获得以下代码:

I am reading some Java text and got the following code:

int[] a = {4,4};
int b = 1;
a[b] = b = 0;

在文中,作者没有给出明确的解释,最后一行的效果是: a [1] = 0;

In the text, the author did not give a clear explanation and the effect of the last line is: a[1] = 0;

我不太清楚我理解:评估是如何发生的?

I am not so sure that I understand: how did the evaluation happen?

推荐答案

让我说清楚这一点,因为人们总是误解这一点:

Let me say this very clearly, because people misunderstand this all the time:

子表达式的评估顺序是独立的关联性和优先级。关联性和优先级确定运算符的执行顺序,但确定子表达式的评估顺序。您的问题是关于子表达式的评估顺序。

Order of evaluation of subexpressions is independent of both associativity and precedence. Associativity and precedence determine in what order the operators are executed but do not determine in what order the subexpressions are evaluated. Your question is about the order in which subexpressions are evaluated.

考虑 A()+ B()+ C()* D()。乘法优先于加法,加法是左关联的,所以这相当于(A()+ B())+(C()* D())但是知道只告诉你第一次加法将在第二次加法之前发生,并且乘法将在第二次加法之前发生。 它没有按顺序告诉你A(),B(),C()和D()将被调用!(它也没有告诉你乘法是在第一个之前还是之后发生的另外。)完全可以遵守优先级和关联性的规则,将其编译为:

Consider A() + B() + C() * D(). Multiplication is higher precedence than addition, and addition is left-associative, so this is equivalent to (A() + B()) + (C() * D()) But knowing that only tells you that the first addition will happen before the second addition, and that the multiplication will happen before the second addition. It does not tell you in what order A(), B(), C() and D() will be called! (It also does not tell you whether the multiplication happens before or after the first addition.) It would be perfectly possible to obey the rules of precedence and associativity by compiling this as:

d = D()          // these four computations can happen in any order
b = B()
c = C()
a = A()
sum = a + b      // these two computations can happen in any order
product = c * d
result = sum + product // this has to happen last

所有的优先级和关联性规则都遵循 - 第一次加法发生在第二次加法之前,乘法发生在第二次加法之前。显然,我们可以在任何顺序中调用A(),B(),C()和D(),并且仍然遵守优先级和关联性规则!

All the rules of precedence and associativity are followed there -- the first addition happens before the second addition, and the multiplication happens before the second addition. Clearly we can do the calls to A(), B(), C() and D() in any order and still obey the rules of precedence and associativity!

我们需要一个与无关的规则来解释优先级和关联性规则,以解释子表达式的计算顺序。 Java(和C#)中的相关规则是子表达式从左到右评估。由于A()出现在C()的左侧,因此首先评估A(),事实上C()涉及乘法而A()只涉及一个加法。

We need a rule unrelated to the rules of precedence and associativity to explain the order in which the subexpressions are evaluated. The relevant rule in Java (and C#) is "subexpressions are evaluated left to right". Since A() appears to the left of C(), A() is evaluated first, regardless of the fact that C() is involved in a multiplication and A() is involved only in an addition.

所以现在你有足够的信息来回答你的问题。在 a [b] = b = 0 中,关联规则表明这是 a [b] =(b = 0); 但这并不意味着 b = 0 首先运行!优先规则说索引的优先级高于赋值,但并不意味着索引器在最右边的赋值之前运行

So now you have enough information to answer your question. In a[b] = b = 0 the rules of associativity say that this is a[b] = (b = 0); but that does not mean that the b=0 runs first! The rules of precedence say that indexing is higher precedence than assignment, but that does not mean that the indexer runs before the rightmost assignment.

优先级和关联性规则强加了以下限制:

The rules of precedence and associativity impose the restrictions that:


  • 索引器操作必须在与左侧赋值操作关联的操作之前运行

  • 与右手赋值操作相关的操作必须在与左手赋值操作相关的操作之前运行。

优先级和关联性只告诉我们分配零 b 必须在之前分配 a [b] 。优先级和关联性没有说明 a [b] 是否在之前 > b = 0 。

Precedence and associativity only tell us that the assignment of zero to b must happen before the assignment to a[b]. Precedence and associativity says nothing about whether the a[b] is evaluated before or after the b=0.

同样,这与以下内容相同: A()[B()] = C() - - 我们所知道的是索引必须在赋值之前发生。我们不知道A(),B()或C()是否基于优先级和关联性首先运行。我们需要另一条规则来告诉我们。

Again, this is just the same as: A()[B()] = C() -- All we know is that the indexing has to happen before the assignment. We don't know whether A(), B(), or C() runs first based on precedence and associativity. We need another rule to tell us that.

规则再次是当你可以选择先做什么时,总是从左到右: a [b] 位于 b = 0 的左侧,所以 a [ b] 先运行 ,结果是 a [1] 。然后发生 b = 0 ,然后将值分配给 a [1] 最后发生。

The rule is, again, "when you have a choice about what to do first, always go left to right": the a[b] is to the left of the b=0, so the a[b] runs first, resulting in a[1]. Then the b=0 happens, and then the assignment of the value to a[1] happens last.

左边的事情发生在右边的事情之前。这是你正在寻找的规则。谈论优先权和关联性既令人困惑又无关紧要。

Things to the left happen before things to the right. That's the rule you're looking for. Talk of precedence and associativity is both confusing and irrelevant.

人们总是把这些东西弄错了,甚至是那些应该知道更好的人。我已经编辑了太多编程书籍,这些编程书规定了规则不正确,因此很多人对优先级/关联性和评估顺序之间的关系完全不正确的信念就不足为奇了 - 即实际上没有这种关系;它们是独立的。

People get this stuff wrong all the time, even people who should know better. I have edited far too many programming books that stated the rules incorrectly, so it is no surprise that lots of people have completely incorrect beliefs about the relationship between precedence/associativity, and evaluation order -- namely, that in reality there is no such relationship; they are independent.

如果您对此主题感兴趣,请参阅我关于该主题的文章以供进一步阅读:

If this topic interests you, see my articles on the subject for further reading:

http://blogs.msdn.com/b/ericlippert/archive/tags/precedence/

它们与C#有关,但大部分内容同样适用于Java。

They are about C#, but most of this stuff applies equally well to Java.

这篇关于Java中评估顺序的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆