Google Guava Function界面中的@Nullable输入会触发FindBugs警告

时间:2022-06-19 20:46:27

The com.google.common.base.Function interface (from Google Guava) defines apply as:

com.google.common.base.Function界面(来自Google Guava)将apply定义为:

@Nullable T apply(@Nullable F input);

@Nullable T apply(@Nullable F输入);

The method has the following javadoc note:

该方法具有以下javadoc注释:

@throws NullPointerException if {@code input} is null and this function does not accept null arguments.

@throws NullPointerException如果{@code input}为null且此函数不接受空参数。

FindBugs complains about my implementation of Function:

FindBugs抱怨我的Function实现:

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;
    }
}

with a high-priority warning:

具有高优先级警告:

NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE, Priority: High

NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE,优先级:高

input must be nonnull but is marked as nullable

输入必须是非空的,但标记为可为空

This parameter is always used in a way that requires it to be nonnull, but the parameter is explicitly annotated as being Nullable. Either the use of the parameter or the annotation is wrong.

此参数始终以要求非空的方式使用,但该参数明确注释为Nullable。使用参数或注释是错误的。

My function does not support null inputs and an exception is thrown if that is the case. If I understand correctly, FindBugs treats this as a requirement for non-null.

我的函数不支持空输入,如果是这种情况则抛出异常。如果我理解正确,FindBugs会将此视为非null的要求。

To me it looks like a contradiction: input is @Nullable but method @throws NullPointerException when it is null. Am I missing something?

对我来说,它看起来像一个矛盾:输入是@Nullable但是当它为null时,方法@throws NullPointerException。我错过了什么吗?

The only way to get rid of the warning that I can see is manual suppression. (Guava code is out of my control, obviously).

摆脱我能看到的警告的唯一方法是手动抑制。 (显然,番石榴代码不受我的控制)。

Who is wrong about the usage of @Nullable annotation, FindBugs, Guava or myself?

使用@Nullable注释,FindBugs,Guava还是我自己错了?

3 个解决方案

#1


28  

Your implementation is wrong ;)

你的实现是错误的;)

Basically docs says (I'll paraphrase and emphasise):

基本上文档说(我会解释并强调):

@throws NullPointerException if input is null and the concrete function implementation does not accept null arguments

@throws NullPointerException如果input为null且具体函数实现不接受null参数

By implementing your function you must decide if it accepts nulls or not. In first case:

通过实现您的功能,您必须确定它是否接受空值。在第一种情况下:

private static final class Example implements Function<MyBean, String> {
    @Override
    @Nullable
    public String apply(@Nullable MyBean input) {
        return input == null ? null : input.field;
    }
}

In second case:

在第二种情况:

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;
    }
}

In both examples returning null is allowed.

在两个示例中,都允许返回null。

EDIT:

Note that Guava uses @javax.annotation.ParametersAreNonnullByDefault on all packages, hence if @Nullable is present it means "suspend global @Nonnull and allow nulls here" and if not it means "nulls forbidden here".

请注意,Guava在所有包上使用@ javax.annotation.ParametersAreNonnullByDefault,因此如果存在@Nullable,则表示“暂停全局@Nonnull并允许此处为空”,如果不是,则表示“此处禁止空值”。

That said, you may want use @Nonnull annotation on your argument or @ParametersAreNonnullByDefault in package to tell FindBugs Function's argument can't be null.

也就是说,您可能希望在您的参数上使用@Nonnull注释或在包中使用@ParametersAreNonnullByDefault来告诉FindBugs函数的参数不能为null。

EDIT 2:

Turns out this case is known issue, see comment #3 (from Guava's lead dev Kevin Bourrillion, about his conversation with Bill Pugh, Findbugs' lead):

事实证明这个案例是已知的问题,请参阅评论#3(来自Guava的主要负责人Kevin Bourrillion,关于他与Bill Pugh的对话,Findbugs的领导):

My reference was a series of in-person conversations with Bill Pugh. He asserted unambiguously that @Nullable means only that some subtypes might accept null. And this seems to be borne out by findbugs for us -- our code passes the nullability checks pretty cleanly (though we should check again since this particular Function change was made).

我的参考是与比尔·普格的一系列现场对话。他毫不含糊地断言@Nullable只意味着某些子类型可能接受null。这似乎是由findbugs为我们证实的 - 我们的代码非常干净地通过了可空性检查(尽管我们应该再次检查,因为这个特定的功能更改已经完成)。

#2


3  

Marking the parameter @Nonnull resolves the issue from findbugs.

标记参数@Nonnull可以解决findbugs的问题。

#3


0  

It seems as though by default Google Guava Functions are @Nullable by default - I was getting Findbugs errors stating that "result must be nonnull but is marked as nullable" when there was no annotation. Adding @Nonnull to the function declaration in the following way helped:

似乎默认情况下Google Guava函数默认是@Nullable - 我得到了Findbugs错误,指出“没有注释时,结果必须是非空的但是被标记为可为空”。以下列方式将@Nonnull添加到函数声明中有助于:

new Function<Object, Object>() {
            @Nonnull
            public Object apply(@Nonnull Object object) {

and now Findbugs is happy. Thanks all

而现在Findbugs很高兴。谢谢大家

#1


28  

Your implementation is wrong ;)

你的实现是错误的;)

Basically docs says (I'll paraphrase and emphasise):

基本上文档说(我会解释并强调):

@throws NullPointerException if input is null and the concrete function implementation does not accept null arguments

@throws NullPointerException如果input为null且具体函数实现不接受null参数

By implementing your function you must decide if it accepts nulls or not. In first case:

通过实现您的功能,您必须确定它是否接受空值。在第一种情况下:

private static final class Example implements Function<MyBean, String> {
    @Override
    @Nullable
    public String apply(@Nullable MyBean input) {
        return input == null ? null : input.field;
    }
}

In second case:

在第二种情况:

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;
    }
}

In both examples returning null is allowed.

在两个示例中,都允许返回null。

EDIT:

Note that Guava uses @javax.annotation.ParametersAreNonnullByDefault on all packages, hence if @Nullable is present it means "suspend global @Nonnull and allow nulls here" and if not it means "nulls forbidden here".

请注意,Guava在所有包上使用@ javax.annotation.ParametersAreNonnullByDefault,因此如果存在@Nullable,则表示“暂停全局@Nonnull并允许此处为空”,如果不是,则表示“此处禁止空值”。

That said, you may want use @Nonnull annotation on your argument or @ParametersAreNonnullByDefault in package to tell FindBugs Function's argument can't be null.

也就是说,您可能希望在您的参数上使用@Nonnull注释或在包中使用@ParametersAreNonnullByDefault来告诉FindBugs函数的参数不能为null。

EDIT 2:

Turns out this case is known issue, see comment #3 (from Guava's lead dev Kevin Bourrillion, about his conversation with Bill Pugh, Findbugs' lead):

事实证明这个案例是已知的问题,请参阅评论#3(来自Guava的主要负责人Kevin Bourrillion,关于他与Bill Pugh的对话,Findbugs的领导):

My reference was a series of in-person conversations with Bill Pugh. He asserted unambiguously that @Nullable means only that some subtypes might accept null. And this seems to be borne out by findbugs for us -- our code passes the nullability checks pretty cleanly (though we should check again since this particular Function change was made).

我的参考是与比尔·普格的一系列现场对话。他毫不含糊地断言@Nullable只意味着某些子类型可能接受null。这似乎是由findbugs为我们证实的 - 我们的代码非常干净地通过了可空性检查(尽管我们应该再次检查,因为这个特定的功能更改已经完成)。

#2


3  

Marking the parameter @Nonnull resolves the issue from findbugs.

标记参数@Nonnull可以解决findbugs的问题。

#3


0  

It seems as though by default Google Guava Functions are @Nullable by default - I was getting Findbugs errors stating that "result must be nonnull but is marked as nullable" when there was no annotation. Adding @Nonnull to the function declaration in the following way helped:

似乎默认情况下Google Guava函数默认是@Nullable - 我得到了Findbugs错误,指出“没有注释时,结果必须是非空的但是被标记为可为空”。以下列方式将@Nonnull添加到函数声明中有助于:

new Function<Object, Object>() {
            @Nonnull
            public Object apply(@Nonnull Object object) {

and now Findbugs is happy. Thanks all

而现在Findbugs很高兴。谢谢大家