Java 中的操作顺序

问题描述 投票:0回答:1

我无法跟踪和理解 Java(和 Javascript)如何处理以下代码:

// Java
int   i = 0;
int[] a = {10, 20, 30, 40, 50, 60};

a[++i] = a[i++] = a[++i] = ++i;
System.out.println(Arrays.toString(a));
// [10, 4, 30, 4, 50, 60]

let   i = 0;
const a = [10, 20, 30, 40, 50, 60];

a[++i] = a[i++] = a[++i] = ++i;
console.log( JSON.stringify(a));  // [10, 4, 30, 4, 50, 60]

运行时,输出为

[10, 4, 30, 4, 50, 60]

我们甚至可以简化这个例子:

int   i = 0;
int[] a = {10, 20};

a[i] = ++i;
System.out.println(Arrays.toString(a));
// [1, 20]

let   i = 0;
const a = [10, 20];

a[i] = ++i;
console.log( JSON.stringify(a) );  // [1, 20]

我预计这会输出

[10, 1]
,因为右手边在前。但输出是
[1, 20]
,但是如何呢?

javascript java
1个回答
0
投票

我预计这会输出

[10, 1]
,因为右手边在前

不,在两种语言中,首先评估

=
的左侧,然后是右侧。

参见15.26.1。当 LHS 是数组访问表达式时,来自 Java 规范的简单赋值运算符 = 关于

=
的求值顺序(我的重点):

如果左侧操作数是数组访问表达式(第 15.10.3 节), 可能用一对或多对括号括起来,然后:

  • 首先,左侧操作数的数组引用子表达式 数组访问表达式被求值...

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

  • 否则,计算右侧操作数

ECMAScript 规范还具有用于首先在第 13.15.2 节中评估左侧的运行时语义

  1. 如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral,那么

    a.让 lref 为 ?评价 左手边表达式。

© www.soinside.com 2019 - 2024. All rights reserved.