何时在表达式中评估/返回/获取Java变量中的值? [英] When are values in Java variables evaluated/returned/fetched in an expression?

查看:92
本文介绍了何时在表达式中评估/返回/获取Java变量中的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 http://introcs.cs.princeton.edu/java/11precedence/,后递增运算符的优先级高于加法运算符.

According to http://introcs.cs.princeton.edu/java/11precedence/, post-increment operator has higher precedence than addition operator.

因此,对于以下代码:

    int i = 1;
    int j = i + i++;
    System.out.println(j);

我以为分配给j的表达式将按以下方式进行评估(评估中的每一行都是步骤"):

I would have thought that the expression assigned to j would have been evaluated as follows (with each line being a "step" in the evaluation) :

   i + i++
   i + (1)   // do post-increment operator; returns 1, and makes i = 2
   (2) + (1)   // do addition operator. need to get the operand i, so do that.
   3

但是当我尝试该程序时,j的值为2.
所以我很困惑.在表达式中,是否会在触摸i ++之前用当前值i替换表达式中的所有"i"?

But when I try this program, the value of j is 2.
So I'm confused. In the expression, does it replace all the "i"s in the expression with the current value of i, BEFORE even touching the i++ ?

这里人们使用的短语评估顺序"帮助我找到以下可能有用的stackoverflow答案:

the phrase "evaluation order" that people here used, helped me to find the following potentially helpful stackoverflow answer: What are the rules for evaluation order in Java? .

我在下面的答案中做出了最大的猜测.我仍然欢迎对此进行更正.

I made my best guess into an answer below. I still welcome corrections to it.

推荐答案

我不完全理解其他人给出的答案,但这是我对正在发生的事情的最佳猜测.如果有人想纠正这个猜测,请这样做.

I do not understand the answers others have given completely, but this is my best guess at what is happening. If someone wants to correct this guess, please do so.

我最好的猜测: a + b * c(其中a,b和c是变量)被制作成表达式树,其中优先级最低的运算符在树的顶部:

My best guess: a + b * c , where a, b, and c are variables, is made into an expression tree, where the operator with lowest precedence is at the top of the tree:

    +
  /   \
 a     *
      / \
     b    c

现在,该树的评估方式如下:+运算符得到评估.为此,它(递归)计算左子树和右子树,然后将这些值相加.

Now, this tree is evaluated like so: the + operator gets evaluated. To do so, it (recursively) evaluates the left subtree, and its right subtree, then adds these values.

这就是发生的一切:

  - addition operator gets evaluated.
    it says "evaluate my left subtree, then my right subtree,
    then add them together. i return that value"
        - left subtree: is a. evaluate variable a into a value.
          (that is, get the value of variable a.)
        - right subtree: i'm a multiplication operator. to evaluate me,
          evaluate my left subtree, then my right subtree, the nmultiply
          them togeter. i return that value.
                - left subtree: is variable b. evalute that.
                - right subtree: is variable c. evaluate that.

这就是为什么a首先完成评估的原因,然后是b,然后是c,然后是b * c,然后是a + (b * c)

This is why it a finishes its evaluation first, then b, then c, then b * c, then a + (b * c)

在带有++ i内容的表达式中,也会发生相同的情况.例如,对于++i + i++,表达式树将如下所示:

In expressions with ++i stuff, the same thing happens. For example, with ++i + i++, the expression tree would look like this:

          +
         / \
    preinc  postinc
       |      |  
       i      i

其中(例如)preinc表示预递增运算符(并且preincrement运算符仅采用一个操作数:一个变量).此处的区别在于,当需要评估以preinc为根的子树时,评估preinc运算符树"并不意味着用变量的值替换操作数中的变量"(例如2 + i),但是它的意思是递增变量i中的值,然后preinc(i)的值就是变量i中的新值".

where (for example) preinc means the preincrement operator (and preincrement operator takes exactly one operand: a variable). the difference here is that when the subtree that has preinc as its root needs to get evaluated, to "evaluate the preinc operator tree" doesn't mean "replace the variable in the operand with the value of the variable" (the way it would for, say, 2 + i ), but instead it means "increment the value in variable i, and then the value of preinc(i) is the new value in the variable i".

以类似的方式,赋值运算符=与2 + i的工作原理略有不同.

in a similar way, the assignment operator = works a little differently than, say, 2 + i.

    int j;
    j = 3;

这里的表达树是

        =
       / \
      j   3

,当需要对以赋值运算符为根的树进行求值时,这意味着左手运算符必须是变量-而不是值!然后求值右子树(我们希望它将其求值为值),然后将值放在右子树中的左子树中的变量中.现在,由=(j,3)返回的值是右子树中的值.

and when a tree with assignment operator as its root needs to get evaluated, this means "the left hand operator must be a variable -- not a value! and then evaluate the right subtree (we expect it to evaluate it to a value), and then put the value in the right subtree in the variable in the left subtree. Now, the value returned by =(j, 3) is the value in the right subtree".

有了这个猜测,我就能正确地提出Java语言规范中关于评估顺序的示例给出的答案(链接为:

with this guess, I'm able to correctly come up with the answers given for examples in the Java Language Specification on Evaluation Order (link is: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.7).

也就是说,如果我绘制表达式树,以下两个示例对我来说是可解决的:
例如:

that is, if i draw the expression tree, the following two examples are solvable by me:
example:

  int i = 2;
  int j = (i = 3) * i;
  System.out.println(j);

示例:

  int b = 9;
  b = b + (b = 3);
  System.out.println(b);

这篇关于何时在表达式中评估/返回/获取Java变量中的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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