IntelliJ 检查:“方法调用可能会产生 NullPointerException”。建议的修复有意义吗?

Posted

技术标签:

【中文标题】IntelliJ 检查:“方法调用可能会产生 NullPointerException”。建议的修复有意义吗?【英文标题】:IntelliJ inspection: 'Method invocation may produce NullPointerException'. Does the suggested fix make sense? 【发布时间】:2019-08-11 21:21:12 【问题描述】:

我经常遇到以下 IntelliJ 检查

private boolean bar()     
    return foo().contains("foo"); // Method invocation 'contains' may produce 'java.lang.NullPointerException'


private String foo() 
    return null;

检查对我来说似乎很好,但是 IntelliJ 建议的修复方法之一(或通常是唯一的)是这样的:

private boolean bar() 
    return Objects.requireNonNull(foo()).contains("foo");

然后警告就消失了。但我不明白这有什么帮助? requireNonNull 将抛出与在 null 上调用 .contains 时无论如何都会抛出的相同的 NullPointerException

通常,IntelliJ 会提出有意义的建议,这是一个常见的建议,所以我在这里漏掉了重点吗?

【问题讨论】:

我同意建议的解决方案并不比问题本身更好。 我猜这个建议在这里毫无意义,因为你得到一个对象并立即使用它。如果您在一个地方获取一个对象并在另一个地方取消引用,则更有意义。这样异常会更早的抛出,效果更好。听起来还是不太合理。 我同意。无论如何,解决方案都会给你NPE:) 【参考方案1】:

使用Objects#requireNonNull 背后的原因类似于返回Optional 背后的原因:你这样做是为了管理期望。

当您返回 Optional<Something> 而不仅仅是 Something 时,您是在说:“嘿,我知道这个 Something 值可能会丢失,所以我没有返回 null 并让您猜测,而是我将返回一个 Optional<Something>,以明确表明您应该期望它可能不存在,并且我希望您在使用它之前检查它是否存在。” 当您在使用 something 之前在代码中调用 Objects.requireNonNull(something) 时,您是在说:“嘿,如果您正在阅读本文,我只是想让您知道我期待这个 something 参数not 为 null,并且我希望您在调用此代码之前确保它不是;因此,我不只是信任您并直接调用 something.contains(...),而是调用 requireNonNull 对在这里和现在说清楚(以防我们中的任何人错过了方法声明中的@NotNull 注释)。”

它能解决问题吗?不,它没有。 IntelliJ 不能神奇地禁止参数为空。但它可以迫使任何阅读该代码的人意识到该参数不应该为空,并推断可能发生这种情况的场景。

【讨论】:

作为负责此子系统的 IntelliJ IDEA 开发人员,我确认此答案是正确的。一般来说,这个想法是foo() 可能在其他地方返回 null,但在这个特定的上下文中,我表明这不应该发生。避免警告比压制更好。

以上是关于IntelliJ 检查:“方法调用可能会产生 NullPointerException”。建议的修复有意义吗?的主要内容,如果未能解决你的问题,请参考以下文章

IntelliJ 检查:“方法调用可能会产生 NullPointerException”。建议的修复有意义吗?

IntelliJ:搜索已检查的异常,在方法签名中声明,但从未在正文中抛出 [关闭]

在 intellij 中调试 sbt 插件并检查其源代码

在 IntelliJ IDEA 上禁用拼写检查

Intellij Community Edition开源项目构建错误 - Groovyc:[静态类型检查]

IntelliJ IDEA 代码检查规范QAPlug