我有一个带有 hasField
函数的类,用于检查字段是否存在且不为空,以及一个 getField
函数,用于返回字段的值(或 null如果不存在)。
在我的代码中,当我在检查 hasField
后立即调用 getField
时,我知道 getField 不会返回 null,但 IDE 检查(恒定条件和异常)不知道这一点。我得到一堆方法方法名称
可能会产生NullPointerException
我正在尝试找到一种干净的方法来消除此警告。
解决方法
这里有一些我可以做的解决方法,但我发现所有这些都很棘手:
- 用
Objects.requireNotnull
包围getField
,代码将是无操作的。我宁愿不这样做,因为它会使代码的可读性稍差。 - 在我知道这是安全的情况下禁止显示警告。同样不是首选,因为这会发生在我们代码中的很多地方。
- 忽略警告。在这种情况下,我们可能会错过合法的警告,因为警告部分的噪音太大。
理想的解决方案
我是否能够以某种方式设置警告,如果 hasField
为 true,则 getField
将返回非空值?我调查了JetBrains Contract Annotations但在这里做我想做的事情似乎超出了 @Contract 支持的范围
代码示例
这是演示该问题的最小工作代码示例:
import javax.annotation.Nullable;
public class Hello {
private Hello(){}
public static void main(String[] args) {
TestClass test1 = new TestClass(null);
if (test1.hasSample()) {
System.out.println(test1.getSample().equals("abc"));
}
}
}
class TestClass {
private final String sample;
TestClass(String field) { this.sample = field; }
boolean hasSample() { return sample != null; }
@Nullable public String getSample() { return sample; }
}
我收到以下警告
Method invocation
equals
may produceNullPointerException
理想情况下,我希望能够在 hasSample 为 true 时告诉 IDE getSample 不为 null。
最佳答案
披露我是负责此子系统的 IntelliJ IDEA 开发人员
不,现在不可能。假设您无法更改 API,没有比您已经列出的可能解决方法更好的解决方案了。我们拥有的最接近的东西是非常简单的方法的内联。但是,它仅在以下情况下有效:
hasSample()
和getSample()
等方法是从同一个类调用的- 被调用的方法不能被重写(private/static/final/final类中声明的)
例如此功能在以下代码中起作用:
final class TestClass { // if final is removed, the warning will appear again
private final String sample;
TestClass(String field) { this.sample = field; }
boolean hasSample() { return sample != null; }
@Nullable
public String getSample() { return sample; }
@Override
public String toString() {
if (hasSample()) {
return "TestClass: "+getSample().trim(); // no warning on trim() invocation here
}
return "TestClass";
}
}
目前,我只能建议将您的 API 重构为可选的,如下所示:
import java.util.Optional;
public class Hello {
private Hello(){}
public static void main(String[] args) {
TestClass test1 = new TestClass(null);
test1.getSample().ifPresent(s -> System.out.println(s.equals("abc")));
// or fancier: test1.getSample().map("abc"::equals).ifPresent(System.out::println);
}
}
final class TestClass {
private final String sample;
TestClass(String field) { this.sample = field; }
public Optional<String> getSample() { return Optional.ofNullable(sample); }
}
关于java - 改进 Intellij 代码检查,以防止可能产生 NullPointerException 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60498381/