当前位置: 首页 > 知识库问答 >
问题:

为什么在检查数组引用表达式是否为null之前要计算Java数组索引表达式?

孟鸿朗
2023-03-14

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

  1. 首先,计算数组引用表达式。如果此计算突然完成,则数组访问由于相同的原因突然完成,并且不计算索引表达式。
  2. 否则,将计算索引表达式。如果此计算突然完成,则数组访问也会出于相同的原因突然完成。
  3. 否则,如果数组引用表达式的值为null,则抛出NullPointerExcture。

所以这段代码将打印:java。lang.NullPointerException,索引=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时抛出NullPointerExcture?或者换句话说——为什么顺序是1,2,3,而不是1,3,2?

共有3个答案

叶鸿
2023-03-14

基本的字节码操作是(对于int[]

ALOAD array_address
ILOAD index
IALOAD array_element_retrieval

IALOAD执行空指针检查。实际上,代码要复杂一些:

  1. 计算数组地址
  2. 计算指数
  3. 我装载

所以答案是:在加载数组地址后,它需要一个额外的检查操作,以预期数组访问。

直接实现的行为。

鱼安然
2023-03-14

这是因为在生成的字节码中没有显式的空检查。

nada()[index = 2]++;

被翻译成以下字节码:

// evaluate the array reference expression
  INVOKESTATIC Test3.nada ()[I
// evaluate the index expression
  ICONST_2
  DUP
  ISTORE 1
// access the array
// if the array reference expression was null, the IALOAD operation will throw a null pointer exception
  DUP2
  IALOAD
  ICONST_1
  IADD
  IASTORE
方风华
2023-03-14

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

数组访问表达式包含两个子表达式,数组引用表达式(左括号前)和索引表达式(括号内)。

这两个子表达式在数组访问表达式本身之前求值,以便对表达式求值。

对两个子表达式求值后

nada()[index = 2]++;

变成

null[2]++;

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

这与Java中大多数表达式的计算是一致的(我能想到的唯一反例是短路运算符,如

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

firstMethod().secondMethod(i = 2);

首先计算firstMethod()i=2,然后如果firstMethod()计算为null,则抛出NullPointerException

 类似资料:
  • 本文向大家介绍计算Java正则表达式的组数,包括了计算Java正则表达式的组数的使用技巧和注意事项,需要的朋友参考一下 通过将多个字符捕获为一组,可以将多个字符视为一个单元。您只需要将这些字符放在一组括号内即可。 您可以使用Matcher类的groupCount()方法计算当前匹配项中的组数。此方法计算当前匹配项中的捕获组数并返回。 示例 输出结果

  • 问题内容: 我有以下一行, 我需要拿这个词ABC, 我写了以下代码片段, 所以,如果我说得到,ABC:但是如果我说是ABC,那么我想知道 这是什么和意味着什么呢?如果有人可以用很好的例子向我解释,那会更好。 正则表达式模式中包含一个:,为什么结果忽略了它?组1是否检测到括号内的所有单词? 因此,如果我再加上两个括号,例如:,那么会有两个小组吗?group(1)将退还零件并退还零件? 给出该代码段的

  • 问题内容: 在Swift中,是否有任何方法可以检查数组中是否存在索引而不会引发致命错误? 我希望我可以做这样的事情: 但是我明白了 致命错误:数组索引超出范围 问题答案: Swift中的一种优雅方式:

  • 问题内容: 我有这种模式: 这对于正数很好用,但是我也需要它做负数,例如“ T-1T3T44”应该工作。或者也许使用空格而不是’T’,所以它应适用于这样的字符串:“-1 2 3 2 -1 6 2”。抱歉,我以前没有真正使用过正则表达式。有什么建议吗?谢谢。 问题答案: 您是否想过尝试: 您会注意到我也将(零个或多个)更改为(一个或多个),因为从技术上讲,这不是数字:-)

  • 以下是我的示例功能文件: 有没有一种方法可以使用空手道表达式检查状态是主动还是不主动? 注意:它肯定可以通过编写托管JS函数来实现。

  • Evaluates simple math expression like 2*4 or 10/2 and outputs its result. You can use \ operator which is equivalent to round(a/b). 计算简单的数学表达式,比如2*4 或 10/2,并输出结果。\ 操作符结果同 round(a/b)。 Very useful in CS