【问题标题】:IntelliJ inspection: 'Method invocation may produce NullPointerException'. Does the suggested fix make sense?IntelliJ 检查:“方法调用可能会产生 NullPointerException”。建议的修复有意义吗?
【发布时间】: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:)

标签: java intellij-idea nullpointerexception intellij-inspections


【解决方案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,但在这个特定的上下文中,我表明这不应该发生。避免警告比压制更好。
猜你喜欢
  • 2020-11-05
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2019-12-06
  • 2015-06-29
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
相关资源
最近更新 更多