java - 检查非空后出现空指针异常

标签 java nullpointerexception java-bytecode-asm javaagents

我在一个不应为 null 的变量上有一个奇怪的 java.lang.NullPointerException。

Object[] params = new Object[10];
if (param1 != null)
    params[0] = param1;

param1 作为方法参数给出,可以为空。 一般情况下,影响param1到params[0]时,不为null(否则不会通过if语句)。

这是错误(第 144 行是“params[0] = param1;”):

Exception in thread "Jalen Agent" java.lang.NullPointerException
    at jalen.MethodStats.onMethodEntry(MethodStats.java:144)
    at hanoi.TowersOfHanoi.solveHanoi(TowersOfHanoi.java)
    at hanoi.TowersOfHanoi.main(TowersOfHanoi.java:29)

这里是出现异常的方法的完整代码:

public static void onMethodEntry(int id, String className, String methodName, Object param1, Object param2, Object param3, Object param4, Object param5) {
    synchronized (globalLock) {
        Object[] params = new Object[10];
        if (param1 != null)
            params[0] = param1;
        if (param2 != null)
            params[1] = param2;
        if (param3 != null)
            params[2] = param3;
        if (param4 != null)
            params[3] = param4;
        if (param5 != null)
            params[4] = param5;
        MethodStats.onMethodEntry(id, className, methodName, params);
    }
}

编辑:

为了阐明我的示例,我处于以下上下文中:

  1. 使用 ASM 检测 Java 应用程序
  2. 在使用 Java 代理的同时运行新的检测类
  3. 代理将使用检测代码收集的信息来运行一些测量
  4. 代理还收集应用程序方法参数的值。

为此,onMethodEntry 在每个方法运行时执行。我有几种具有不同签名的方法。特别是:

public static void onMethodEntry(int id, String className, String methodName, Object[] params) {
    synchronized (globalLock) {
        StringBuilder fullMethodName = new StringBuilder(className).append('.').append(methodName).append('-').append(Thread.currentThread().getId());
        MethodStats.addNewMethod(id, fullMethodName.toString());
        System.out.println(fullMethodName.toString() + " -- " + id);
        for (Object param : params) {
            if (param != null)
                System.out.println("Param: " + param.toString());
        }
        startTimes[depth] = System.nanoTime();
        stack[depth++] = MethodStats.getMethodInfo(id);
    }
}

public static void onMethodEntry(int id, String className, String methodName, Object param1) {
    synchronized (globalLock) {
        Object[] params = new Object[10];
        if (param1 != null)
            params[0] = param1;
        MethodStats.onMethodEntry(id, className, methodName, params);
    }
}

public static void onMethodEntry(int id, String className, String methodName, Object param1, Object param2) {
    synchronized (globalLock) {
        Object[] params = new Object[10];
        if (param1 != null)
            params[0] = param1;
        if (param2 != null)
            params[1] = param2;
        MethodStats.onMethodEntry(id, className, methodName, params);
    }
}

这是我用于检测程序类(即汉诺塔)的代码:

public void visitCode() {
    mv.visitLdcInsn(new Integer(this.methodID));
    this.visitLdcInsn(this.className);
    this.visitLdcInsn(this.methodName);
    String paramCall = "";
    if (this.numParam > 0) {
        // Load parameters
        for (int i=1; i<=this.numParam; i++) {
            this.visitVarInsn(Opcodes.ALOAD, i);
            paramCall += "Ljava/lang/Object;";
        }
    }
    System.out.println(paramCall);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC,
            "jalen/MethodStats",
            "onMethodEntry",
            "(ILjava/lang/String;Ljava/lang/String;" + paramCall + ")V");
    super.visitCode();
}

最佳答案

首先,错误不是params[0] = param1 行,因为堆栈跟踪显示您的代码进入了 onMethodEntry 方法。

添加 if 语句绝对没有意义:如果 param1null,则没有 null 分配,但 params[0]保持 null 因为 new Object[10] 中所有未分配的位置最初设置为 null

为了解决这个问题,你应该首先弄清楚哪些对象必须放在数组中而不是null参数,然后修改条件如下:

if (param1 != null) {
    params[0] = param1;
} else {
    params[0] = // something else
}

关于java - 检查非空后出现空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13530986/

相关文章:

将xls数据导入mysql数据库的java代码

java - 确定 catch block 在哪里结束 ASM

java - 计算方法的字节码大小

java - Android-decodeBase64 导致应用程序崩溃

java - Map<Integer, List<courseCLS>> 到 Map<Integer, List<Course>>

java - 如何从 KIE 工作台获取 kieContainer

java - 添加 EditText 时 Fragment 中出现 NullPointerException

java - 如何解决 "Exception in thread "AWT-EventQueue-0"java.lang.NullPointerException"?

java - 使用 ASM 访问 Java Stack 中的第二个顶级对象

java - 如何解决lint warning "field is never used"but it is serialized