java - 为什么在检查数组引用表达式是否为空之前评估 Java 数组索引表达式?

标签 java language-lawyer

根据 JLS,数组访问表达式的运行时求值行为如下:

  1. 首先,计算数组引用表达式。如果这 评估突然完成,然后数组访问完成 突然出于同样的原因,索引表达式不是 评估。
  2. 否则,将计算索引表达式。如果这 评估突然完成,然后数组访问完成 突然出于同样的原因。
  3. 否则,如果数组的值 引用表达式为 null,则抛出 NullPointerException。

所以这段代码会打印:java.lang.NullPointerException, index=2

class Test3 {
    public static void main(String[] args) {
        int index = 1;
        try {
            nada()[index = 2]++;
        } catch (Exception e) {
            System.out.println(e + ", index=" + index);
        }
    }

    static int[] nada() {
        return null;
    }
}

问题是:为什么我们需要首先计算 index = 2 表达式,而不是在数组引用被计算为 null 时抛出 NullPointerException?或者换句话说 - 为什么顺序是 1,2,3 而不是 1,3,2?

最佳答案

一个数组访问表达式有两个子表达式:

An array access expression contains two subexpressions, the array reference expression (before the left bracket) and the index expression (within the brackets).

这两个子表达式在数组访问表达式本身之前被计算,以便计算表达式。

计算两个子表达式后

nada()[index = 2]++;

变成

null[2]++;

现在只计算表达式并抛出 NullPointerException

这与 Java 中大多数表达式的求值一致(我能想到的唯一反例是短路运算符,例如 && 和 ||)。

例如,如果您进行以下方法调用:

firstMethod().secondMethod(i = 2);

首先你评估 firstMethod()i = 2,然后你才抛出 NullPointerException if firstMethod() 评估为 null

关于java - 为什么在检查数组引用表达式是否为空之前评估 Java 数组索引表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55160799/

相关文章:

c++ - `std::multimap` 是否保证每个键的实际值在相等范围内?

c++ - C 或 C++ 是否保证 array < array + SIZE?

c++ - 那么为什么 i =++i + 1 在 C++11 中定义良好?

java - 将 ID 从查询转换为字符串

java - 如何为整个 Activity 添加 ScrollView ?

java - 通过计划任务进行批量操作的正确方法?

c++ - 只有未指定数量的参数的函数的目的是什么?

c - union 或 struct 允许从未初始化的实例赋值吗?

java - Android Studio (Intellij) 编译错误

java - 用于 Java 的 Visual Studio?