是否首先评估数组索引或指定值?

时间:2013-12-02 22:34:01

标签: java arrays

如果我有以下代码:

array[index] = someValue;

首先评估someValueindex吗?

2 个答案:

答案 0 :(得分:18)

首先评估索引。请参阅JLS section 15.26.1,特别是:

  

<强> 15.26.1。简单分配操作员=

     

...

     

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

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

  2.   
  3. 否则,左侧操作数数组的索引子表达式   访问表达式被评估。如果此评估突然完成,   然后,由于同样的原因,赋值表达式突然完成   并且不评估右侧操作数,也不进行任何分配。

  4.   
  5. 否则,将评估右侧操作数。如果这个评价   突然完成,然后赋值表达式突然完成   出于同样的原因,没有任何转让。

  6.   

TL; DR :订单 1 [2] = 3

答案 1 :(得分:6)

看起来首先评估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)