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

A1m*_*A1m 5 java intellij-idea nullpointerexception intellij-inspections

我通常会遇到以下 IntelliJ 检查

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

private String foo() {
    return null;
}
Run Code Online (Sandbox Code Playgroud)

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

private boolean bar() {
    return Objects.requireNonNull(foo()).contains("foo");
}
Run Code Online (Sandbox Code Playgroud)

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

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

wal*_*len 5

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

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

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

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