【问题标题】:Is the array index or the assigned value evaluated first? [duplicate]是先评估数组索引还是赋值? [复制]
【发布时间】:2013-12-02 22:34:01
【问题描述】:

如果我有以下代码:

array[index] = someValue;

someValueindex 是否首先得到评估?

【问题讨论】:

  • @Nambari 我可以举个例子,但会相当复杂。
  • 易于检查:array[-1] = someMethodThatPrintsSomething();
  • @alfasin 是否可以保证它始终以一种方式运行?我不能只是测试。
  • 您是否希望 JVM 每次都表现不同?这个问题不涉及任何竞争条件或任何具有“意外行为”的东西。

标签: java arrays


【解决方案1】:

首先评估索引。见JLS section 15.26.1,特别是:

15.26.1。简单赋值运算符 =

...

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

  1. 一、左侧操作数的数组引用子表达式 评估数组访问表达式。如果此评估完成 突然,然后赋值表达式突然完成 同样的原因;索引子表达式(左侧操作数数组的 访问表达式)和右手操作数不被评估,也没有 分配发生。

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

  3. 否则,将计算右侧操作数。如果这个评价 突然完成,然后赋值表达式突然完成 出于同样的原因,没有分配发生。

TL;DR:顺序是1[2]=3

【讨论】:

    【解决方案2】:

    看起来index 表达式首先被求值。

    这个测试程序证实了这一点:

    public class Main {
       public static void main(String[] args) {
          int[] array = new int[10];
          array[getIndex()] = getValue();
       }
    
    
       private static int getIndex() {
          System.out.println("getIndex!");
          return 0;
       }
    
       private static int getValue() {
          System.out.println("getValue!");
          return 1;
       }
    }
    

    输出:

    getIndex!
    getValue!
    

    即使抛出ArrayIndexOutOfBoundsException,也会评估该值。更改getIndex()

    private static int getIndex() {
       System.out.println("getIndex!");
       return -1;  // Hey!
    }
    

    输出:

    getIndex!
    getValue!
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
        at Main.main(Main.java:11)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
    

    【讨论】:

    • 问题是,它会对每个 JVM 都这样做吗?有保证吗?
    • @tbodt 是的,每个编译器都会生成以这种方式运行的代码;评估顺序在 JLS 中指定。
    • 这是一个编译器问题而不是 JVM 问题。来自 jls The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
    • @Downvoter 请解释什么是错误的/可以纠正的。
    猜你喜欢
    • 2014-08-01
    • 2010-12-17
    • 2011-07-19
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多