Java 改进的Intellij代码检查可能会产生NullPointerException警告
我有一个类,它有一个Java 改进的Intellij代码检查可能会产生NullPointerException警告,java,intellij-idea,annotations,code-inspection,Java,Intellij Idea,Annotations,Code Inspection,我有一个类,它有一个hasField函数检查字段是否存在且不为null,还有一个getField函数返回字段的值(如果不存在则为null) 在我的代码中,当我在检查hasField之后立即调用getField时,我知道getField不会返回null,但是IDE检查(常量条件和异常)不知道这一点。我得到一堆方法方法名可能会产生空点异常 我正试图找到一个干净的方法让这个警告消失 解决办法 以下是我可以做的一些变通方法,但我发现所有这些方法都有问题: 用对象包围getField。requireNot
hasField
函数检查字段是否存在且不为null,还有一个getField
函数返回字段的值(如果不存在则为null)
在我的代码中,当我在检查hasField
之后立即调用getField
时,我知道getField不会返回null,但是IDE检查(常量条件和异常)不知道这一点。我得到一堆方法方法名
可能会产生空点异常
我正试图找到一个干净的方法让这个警告消失
解决办法
以下是我可以做的一些变通方法,但我发现所有这些方法都有问题:
对象包围getField
。requireNotnull
,代码将是不可操作的。我们不希望这样做,因为这样会使代码的可读性稍差hasField
为真,那么getField
将返回非空值?我研究了一下,但在这里做我想做的事情似乎超出了@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
理想情况下,当hasSample为true时,我希望能够告诉IDE getSample不为null。我是负责此子系统的IntelliJ IDEA开发人员
不,现在不可能了。假设您不能更改API,没有比您已经列出的可能解决方案更好的解决方案了。我们拥有的最接近的东西是非常平凡的方法的内联。但是,它仅在以下情况下有效:
- 像
和hasSample()
这样的方法是从同一个类调用的getSample()
- 无法重写被调用的方法(private/static/final/在final类中声明)
final类TestClass{//如果删除final,警告将再次出现
私人最终字符串样本;
TestClass(字符串字段){this.sample=field;}
布尔hasSample(){返回样本!=null;}
@可空
公共字符串getSample(){return sample;}
@凌驾
公共字符串toString(){
if(hasSample()){
return“TestClass:+getSample().trim();//此处没有关于trim()调用的警告
}
返回“TestClass”;
}
}
目前,我只能建议您将API重构为如下选项:
import java.util.Optional;
公共课你好{
私有Hello(){}
公共静态void main(字符串[]args){
TestClass test1=新的TestClass(null);
test1.getSample().ifPresent(s->System.out.println(s.equals(“abc”));
//或者fancier:test1.getSample().map(“abc”::equals).ifPresent(System.out::println);
}
}
最终类TestClass{
私人最终字符串样本;
TestClass(字符串字段){this.sample=field;}
公共可选getSample(){return Optional.ofNullable(sample);}
}
感谢您的快速回复。现在我决定忽略这些警告。