我有一个带有hasField
函数的类,该函数检查某个字段是否存在并且不为空,而一个getField
函数则返回该字段的值(如果不存在,则为null)。 / p>
在我的代码中,当我在检查getField
之后立即调用hasField
时,我知道getField不会返回null,而是IDE检查(恒定条件和异常 )不知道。我得到了一堆方法method name
可能会产生一个NullPointerException
我正在尝试寻找一种清除此警告的干净方法。
解决方法
以下是我可以做的一些解决方法,但我发现所有这些技巧都很简单:
getField
与Objects.requireNotnull
环绕在一起,代码将变为空操作。最好不要这样做,因为这会使代码的可读性稍差。理想的解决方案
我能够以某种方式设置警告,如果hasField
为true,那么getField
将返回非null吗?我调查了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; }
}
我收到以下警告
方法调用
equals
可能会产生NullPointerException
理想情况下,我希望能够告诉IDE当hasSample为true时getSample不为null。
答案 0 :(得分:2)
公开信息我是负责此子系统的IntelliJ IDEA开发人员
否,现在不可能。假设您无法更改API,没有比您已经列出的可能解决方法更好的解决方案。我们拥有的最接近的东西是非常琐碎的方法的内联。但是,它仅在以下情况下有效:
hasSample()
和getSample()
之类的方法例如此功能在以下代码中起作用:
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重构为这样的Optionals:
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); }
}