【问题标题】:A good way to debug nullPointerException [closed]调试 nullPointerException 的好方法 [关闭]
【发布时间】:2013-07-26 03:51:55
【问题描述】:

我正在使用 eclipse 和 java 编程。有时我会遇到一个会困扰我几个小时的 nullPointerException。有没有办法更好地调试 nullPointerExceptions 并找出变量值是什么以及其他会导致 null 指针异常的事情。

【问题讨论】:

  • 查看堆栈跟踪...它显示了哪一行抛出了 NPE,您可以在那里放置一个断点并查看哪个变量为空...
  • 学习如何调试 NPE 的最佳方法是不断调试它们。随着时间的推移,你会变得更好。但关键是找出它发生在哪里,然后检查变量。这里没有魔法。
  • 您可以将assert 语句放入您的代码中
  • 呃,看看异常跟踪,看看哪里出错了。在那里停下来(或插入打印语句)以确定什么值为空。将该值追溯到其来源。
  • 异常不是告诉你哪一行有错误吗?任何给定的代码行都不应该做很多事情,并且任何给定的函数理想情况下应该只有几行代码(或者即使它有很多行也非常简单)。确定任何给定函数中的 null 值的来源应该不难。

标签: java debugging nullpointerexception


【解决方案1】:

查看堆栈跟踪并读取抛出NullPointerException 的行号。几乎总是,该行有一些方法调用,如

x.getValue()

如果xnull,你会得到NullPointerException。如果堆栈跟踪顶部的方法不是您的代码,请一直跟踪堆栈,直到您到达您的代码。在这种情况下,您经常将null 传递给不喜欢null 参数的方法。找到它并修复它。

此外,当您遇到不属于您的方法抛出NullPointerException 时,请阅读文档。比如看String.replace(CharSequence target, CharSequence replacement)

投掷

NullPointerException - 如果targetreplacementnull

没有比这更清楚的了!

这是一个例子:

查看第 4 行,我们看到 foo.bar()。这意味着foonull。那很容易。我们再看一个例子:

追溯您的代码,我们看到s.replace(target, replacement) 正在抛出。我们应该检查targetreplacement。让我们附加一个调试器:

啊哈! replacementnull。您可以在 Eclipse 中做同样的事情。在抛出异常时设置断点,并使用它来检查方法的参数。我在这里很原始,因为我来自一个思想流派,我真诚地相信,如果每个人都先学会以艰难的方式去做,就会变得更好。泄漏抽象等等。

【讨论】:

  • 一个例子或带有手绘圆圈的截图会很好:)
  • 我的问题是,对于像 function(a, b, c, d, e) 这样的函数,它不会告诉您其中哪个变量为空。
  • @hexafraction:甚至更好,8x10 的光面图片,带有圆圈和箭头,每张背面都有一段解释每张图片的用途。
  • @HovercraftFullOfEels 我有一些,但杰森带着一只导盲犬走进来。
  • @HovercraftFullOfEels - 你忘了狗会闻到脚印。
【解决方案2】:
  1. 在调试时可以使用BreakPoints 视图来捕获空 指针。

    窗口 -> 显示视图 -> 断点

    在视图中有一个"J!" 可以让你设置断点 例外。您可以设置java.lang.NullPointerException。所以一次 抛出空指针异常,可以查看是哪个变量引起的 空。

  2. 您可以做的其他事情是在编码时捕获可能的空指针访问。偏离路线,您无法使用此设置捕获所有空指针。但它仍然很有帮助,请在 eclipse 中设置以下设置。

    首选项 -> Java -> 编译器 -> 错误/警告 -> 空分析

【讨论】:

【解决方案3】:

有几种方法可以让NullPointerException 不再成为问题:

  1. 使用@Nullable annotation

  2. 在构造函数和 setter 中测试 null 的参数值(避免使用普通的旧 Java 代码中的 setter)。如果你经常这样做,你可以制作一个(Eclipse)源代码模板来快速生成代码。这被称为“failfast”——当值在代码中被进一步使用时,你不需要等待抛出异常,例如将其存储在字段中之后。

  3. 确保每行执行最少数量的操作(例如 1 或 2 次)。如果不这样做,则必须找出在单行表达式中NullPointerException 出现的位置。

  4. 不要在字段中使用null 来指示状态。相反,使用例如一个enum State。例如。不要这样做if (socket == null) { // not connected },因为稍后很容易忘记检查null。明确的状态不是那么容易忘记的。

  5. 除非明确需要,否则不要将局部变量初始化为 null。实际上,如果您正确处理范围和异常,您应该能够标记大多数变量final。用throw new IllegalStateException("Unhandled program state", e) 替换默认的printStacktrace() 方法会有所帮助,因为它被视为代码块的退出点。

大量编程后你会发现NullPointerExceptions 的数量减少了。

【讨论】:

    猜你喜欢
    • 2010-11-10
    • 1970-01-01
    • 2017-01-06
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多