5
public class Conversions {

        public static void main(String[] args) {

                    int index = 3;
                    int[] arr = new int[] { 10, 20, 30, 40};

                    arr[index] = index = 2; //(1)
                    System.out.println("" + arr[3] + " " + arr[2]);

            }
    }

我有这个,它给出了:

2 30 

我希望它会给

40 2

在 (1) 为什么赋值中的索引值没有更改为 2(并保持为 3)。?

4

3 回答 3

11

Java 语言规范 (JLS)第 15.26 节暗示的右关联性意味着您的表达式可以表示为tree,因此:=

           =
    +------+-------+
    |              |
arr[index]         =
              +----+----+
              |         |
            index       2

但是,第 15.7 节指出:

Java 编程语言保证运算符的操作数看起来是以特定的评估顺序进行评估的,即从左到右。

因此,在is之前arr[index]评估,即更新的值之前。 index = 2index


显然,你不应该编写依赖于这个事实的代码,因为它依赖于几乎没有读者理解的规则。

于 2013-07-22T00:00:21.200 回答
5

Java 语言规范:15.26.1。简单赋值运算符=

如果左侧操作数是数组访问表达式(第 15.13 节),可能包含在一对或多对括号中,则:

  • 首先,评估左侧操作数数组访问表达式的数组引用子表达式。如果这个求值突然完成,那么赋值表达式也会因为同样的原因而突然完成;(左侧操作数数组访问表达式的)索引子表达式和右侧操作数不被计算并且不发生赋值。

  • 否则,将评估左侧操作数数组访问表达式的索引子表达式。如果此评估突然完成,则赋值表达式出于同样的原因突然完成,并且不会评估右侧操作数并且不会发生赋值。

  • 否则,评估右侧操作数。如果这个求值突然完成,那么赋值表达式也会因为同样的原因而突然完成并且没有赋值发生。

  • [...](解释了进一步的步骤)

如您所见,索引是在赋值右侧之前评估的。

于 2013-07-22T00:01:24.080 回答
1
  1. 首先评估数组索引标头,以得出分配 ( arr[index]) 的适当位置。
  2. 以下所有运算符都经过优先级评估,并发现相等(所有运算符都是赋值,因此具有相同的优先级)。
  3. 然后根据关联性评估操作数,关联性对于赋值运算符是从右到左的。
于 2013-07-22T00:05:50.747 回答