数组表达式
例:A[(A=B)[3]]
A:数组表达式;
B:数组表达式;
(A=B)[3]:索引表达式;
数组计算过程
- 首先,数组引用表达式计算。如果该计算猝然结束,那么数组表达式也会以相同的方式结束,索引表达式不会计算;
- 否则,索引表达式被计算。如果该计算猝然结束,那么数组访问也会以相同的方式猝然结束;
- 如果,数组引用表达式的值为null,那么会抛出一个NullPointerException实例;
- 否则,数组引用表达式的值确实引用的是数组。如果索引表达式的值小于0,或者大于等于数组的长度,那么会抛出ArrayIndexOutOfBoundsException实例;
- 否则,数组访问的结果是类型T的变量,该变量在数组中,由索引表达式的值选中;
实例
public class ArrayTest {
public static void main(String[] args) {
m1();
m2();
m3();
m4();
}
/**
* 数组引用首先被计算
*/
private static void m1() {
int[] a = {11, 12, 13, 14};
int[] b = {0, 1, 2, 3};
System.out.println("m1():" + a[(a = b)[3]]);
}
/**
* 数组引用计算的猝然结束
*/
private static void m2() {
int index = 1;
try {
skedaddle(2)[index = 2]++;
} catch (Exception e) {
System.err.println("m2():" + e + ", index=" + index);
}
}
/**
* Null数组引用
*/
private static void m3() {
int index = 1;
try {
skedaddle(3)[index = 2]++;
} catch (Exception e) {
System.err.println("m3():" + e + ", index=" + index);
}
}
/**
* NullPointerException永远都不会发生,
* 因为索引表达式必须在数组访问发生之前完成计算,
* 而在数组访问中才包含对数组引用表达式的值是否为null进行检查;
*/
private static void m4() {
int[] a = null;
try {
int i = a[vamoose()];
System.out.println("m4():" + i);
} catch (Exception e) {
System.err.println("m4():" + e);
}
}
private static int vamoose() throws Exception {
throw new Exception("Twenty-three skidoo!");
}
private static int[] skedaddle(int x) throws Exception {
if (x == 3)
return null;
throw new Exception("Ciao");
}
}
结果: