【问题标题】:Can Java's NullPointerException be changed to report on which variable was null? [duplicate]是否可以更改 Java 的 NullPointerException 以报告哪个变量为空? [复制]
【发布时间】:2012-09-17 11:50:18
【问题描述】:

Java 中的NullPointerException 似乎只报告它发生在特定的代码行上。如果一行代码中使用了多个变量,是否可以更改该异常以声明哪个变量为空?

【问题讨论】:

  • 遗憾的是,它会很有用
  • 这行代码还不够吗?
  • @Lirik 我认为显而易见的答案是是的。对于意大利面条代码,答案是恐怕......
  • 为什么不将调试器指向那行代码并确定哪个变量为空。您的代码结构是否不正确,以至于您在单行中有几个变量?
  • @pankar 问题确实出在链式方法调用中。如果我将something.getThis().getThat().getAnotherThing().whyAmIStillChaining().seriouslyWtf() 全部放在一行上并获得一个 NPE,唯一简单的解决方法是将其全部拆开并重新编译/重新运行。这就是为什么我希望他们将Elvis operator 放入 Java 7 中。哦,好吧。我最近也遇到了这个问题-.-

标签: java nullpointerexception


【解决方案1】:

不,类文件中的调试信息不​​包含足够的信息来允许这样做。

但是,您可以改善这种情况。有两件事会导致 NPE 被抛出:

  • . 取消引用变量,例如 foo.bar()
  • [ 索引数组,如 args[0]

如果您编写的代码在给定的代码行中只有 一个,那么毫无疑问是哪一个导致了 NPE。它将引入 lot 的临时变量,但在调试时您可以获得更多信息。

【讨论】:

  • 自动拆箱也是空指针的可能原因。
  • 我没想到。关于自动装箱/拆箱,我一直站在围栏的两边,但我想我可能会站在一边说“尽可能少的魔法”。换句话说,找出如何让编译器将自动装箱用法标记为错误并手动显式进行转换。我相信Eclipse编译器可以做到这一点,但没有检查。
  • 实际上,有足够的信息来解决这个问题。您可以找出触发此 NPE 被抛出的指令。它将归结为一个invokevirtual 指令,它只需要一个操作数。然后你可以追踪到它被调用的对象——只需要一点点工作
  • @OneTwoThree 很有趣。你有更详细描述的链接吗?
【解决方案2】:

没有。 NullPointerException 不一定是由变量/标识符为null 引起的。例如。 throw new NullPointerException()throw null。虽然经常这样,但并不是严格要求的。

在大多数情况下,导致 NPE 的原因是相当明显的。如果没有,那么您可能在一行代码中发生了太多事情。

考虑这个用例:

foo.doWork(bar1, bar2, bar3);

这里很明显foo 是`null。

另一种情况:

foo.doWork(bar.get(), bar2.get())

这里可能是foobarbar2

关键是,有了这些信息和断点,null 应该是显而易见的。如果情况变得更糟,像FindBugs 这样的静态代码分析器也可以给你一些提示。

【讨论】:

  • NPE 还有什么原因造成的?
  • 呃,迭代案例会很困难。但它可以作为守卫模式的一部分抛出。基本上,一个方法检查其参数是否为null,然后在工作之前抛出一个 NPE。例如,一些集合这样做是为了避免破坏数据结构。其他应用可能只是避免自然发生的 NPE。
  • 一个随机的糟糕编码器可能会为了好玩而抛出一个 NPE。
  • @DaveNewton 你也可以从自动装箱中得到一个 NPE,比如做Integer val = null 然后把它传递给someMethod(int i) 像这样:someMethod(val);
  • 所以,都是由变量引起的,除非显式抛出。
猜你喜欢
  • 2011-10-18
  • 2019-07-04
  • 1970-01-01
  • 2014-01-18
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
  • 1970-01-01
相关资源
最近更新 更多