Java @Google Guava函数接口中的可空输入触发FindBugs警告
Java @Google Guava函数接口中的可空输入触发FindBugs警告,java,guava,findbugs,Java,Guava,Findbugs,com.google.common.base.Function接口(from)将apply定义为: @Nullable T apply(@Nullable F input) 该方法具有以下javadoc注释: @如果{@code input}为null且此函数不接受null参数,则抛出NullPointerException FindBugs抱怨我的功能实现: private static final class Example implements Function<MyBean, St
com.google.common.base.Function
接口(from)将apply
定义为:
@Nullable T apply(@Nullable F input)代码>
该方法具有以下javadoc注释:
@如果{@code input}为null且此函数不接受null参数,则抛出NullPointerException
FindBugs抱怨我的功能实现:
private static final class Example implements Function<MyBean, String> {
@Override
@Nullable
public String apply(@Nullable MyBean input) {
if (null == input) {
throw new NullPointerException();
}
return input.field;
}
}
private静态最终类示例实现函数{
@凌驾
@可空
公共字符串apply(@Nullable MyBean input){
if(null==输入){
抛出新的NullPointerException();
}
返回input.field;
}
}
具有高优先级的警告:
NP_参数_必须_为非空,但_标记为可空,优先级:高
输入必须为非Null,但标记为可为Null
此参数的使用方式始终要求其为非Null,但该参数被显式注释为可为Null。参数或注释的使用是错误的
我的函数不支持null
输入,如果是这种情况,将引发异常。如果我理解正确,FindBugs会将此视为非null的要求
在我看来,这似乎是一个矛盾:输入是@Nullable的,但方法@null时抛出NullPointerException。我错过什么了吗
摆脱我所看到的警告的唯一方法是手动抑制。(番石榴的代码显然超出了我的控制范围)
谁对@Nullable annotation、FindBugs、Guava或我的用法有错?您的实现是错误的;)
基本上,docs说(我将解释并强调):
@如果input
为空且具体值为空,则抛出NullPointerException
函数实现不接受空参数
通过实现函数,您必须决定它是否接受null。在第一种情况下:
private static final class Example implements Function<MyBean, String> {
@Override
@Nullable
public String apply(@Nullable MyBean input) {
return input == null ? null : input.field;
}
}
private静态最终类示例实现函数{
@凌驾
@可空
公共字符串apply(@Nullable MyBean input){
返回input==null?null:input.field;
}
}
在第二种情况下:
private static final class Example implements Function<MyBean, String> {
@Override
@Nullable
public String apply(MyBean input) {
if (null == input) {
throw new NullPointerException();
}
return input.field;
}
}
private静态最终类示例实现函数{
@凌驾
@可空
公共字符串应用(MyBean输入){
if(null==输入){
抛出新的NullPointerException();
}
返回input.field;
}
}
在这两个示例中,都允许返回null
编辑:
请注意,Guava在所有包上默认使用@javax.annotation.ParametersAreNonnull
,因此如果存在@Nullable
,则表示“挂起全局@Nonnull
并允许此处为空”,否则表示“此处禁止为空”
也就是说,您可能希望在参数上使用@Nonnull
注释,或者在包中使用@parameters默认情况下为nonnully
,告诉FindBugs函数的参数不能为null
编辑2:
事实证明,见评论3(来自Guava的负责人dev Kevin Bourrillion,关于他与Findbugs的负责人Bill Pugh的对话):
我的参考资料是与比尔·普格的一系列面对面的谈话。
他毫不含糊地断言,@Nullable
只意味着某些子类型
可能接受null。findbugs为我们证明了这一点——我们的代码非常干净地通过了可空性检查(尽管我们
应再次检查,因为进行了此特定功能更改)
标记参数@Nonnull
解决了findbugs的问题。似乎默认情况下Google Guava函数默认为@Nullable-当没有注释时,我收到findbugs错误声明“结果必须为非null,但标记为null”。通过以下方式将@Nonnull添加到函数声明中有助于:
new Function<Object, Object>() {
@Nonnull
public Object apply(@Nonnull Object object) {
新函数(){
@非空
公共对象应用(@Nonnull对象){
现在Findbugs很高兴。谢谢大家你说你将接受签名中的null,然后你拒绝了正文中的null值。听起来你好像误解了@Nullable
的目的。我为输入参数添加@Nullable
的唯一原因是它是函数
接口定义的s、 无论如何,我按照@Xaerxess的建议从参数中删除了@Nullable
注释,但FindBugs一直在抱怨。如果不从接口中删除注释,则将其添加到实现中。如果函数
允许您使用null作为参数,这并不意味着您必须在impl中允许null,就像函数
合同状态。注释已由框架接口指定,我无法(也不打算)从中删除。我唯一可以编辑的代码是我自己的代码(=实现)。我从实现中删除了@Nullable注释,但FindBugs一直在抱怨。标记为@javax.annotation.Nonnull
-但没有帮助,仍然得到此参数的使用方式始终要求它为非Null,但该参数被显式注释为可为Null。
@vitaly似乎这是一个错误这可能取决于您使用的FindBugs版本。您使用的是FindBugs 2.X,根据Guava的问题,我会说它是FindBugs 2.X bug;)