La entrada @Nullable en la interfaz de función de Guayaba de Google activa la advertencia de FindBugs


La interfaz com.google.common.base.Function (de Google Guava) define apply como:

@Nullable T apply(@Nullable F input);

El método tiene la siguiente nota javadoc:

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

FindBugs se queja de mi implementación de la función:

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

Con una de alta prioridad advertencia:

NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE, Prioridad: Alta

La entrada debe ser nonnull pero está marcada como nullable

Este parámetro siempre se usa de una manera eso requiere que sea nonnull, pero el parámetro está anotado explícitamente como Nullable. El uso del parámetro o de la anotación es incorrecto.

Mi función no soporta entradas null y se lanza una excepción si ese es el caso. Si entiendo correctamente, FindBugs trata esto como un requisito para non-null.

Para mí parece una contradicción: la entrada es @Nullable pero el método @arroja NullPointerException cuando es null. Me estoy perdiendo algo?

La única manera de deshacerse de la advertencia que puedo ver es la supresión manual. (El código de guayaba está fuera de mi control, obviamente).

¿Quién se equivoca sobre el uso de la anotación @Nullable, FindBugs, Guayaba o yo mismo?

Author: vitaly, 2012-09-14

3 answers

Su implementación es incorrecta;)

Básicamente los documentos dicen (parafraseando y enfatizando):

@throws NullPointerException si input es nulo y el hormigón la implementación de la función no acepta argumentos nulos

Al implementar su función debe decidir si acepta nulos o no. En el primer caso:

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

En el segundo caso:

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

En ambos ejemplos se permite devolver null.

EDITAR:

Nota que Guava usa @javax.annotation.ParametersAreNonnullByDefault en todos los paquetes, por lo tanto si @Nullable está presente significa "suspender global @Nonnull y permitir nulos aquí" y si no significa "nulos prohibidos aquí".

Dicho esto, es posible que desee usar @Nonnull anotación en su argumento o @ParametersAreNonnullByDefault en el paquete para indicar que el argumento de la función FindBugs no puede ser nulo.

EDITAR 2:

Resulta que este caso es un problema conocido , ver el comentario # 3 (del líder de desarrollo de Guayaba Kevin Bourrillion, sobre su conversación con Bill Pugh, Findbugs ' lead):

Mi referencia fue una serie de conversaciones en persona con Bill Pugh. Afirmó inequívocamente que @Nullable significa solo que algunos subtipos podría aceptar null. Y esto parece ser confirmado por findbugs para nosotros our nuestro código pasa las comprobaciones de nullability bastante limpiamente (aunque debe comprobar de nuevo ya que se realizó este cambio de función en particular).

 28
Author: Xaerxess,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-14 15:05:16

Marcar el parámetro @Nonnull resuelve el problema de findbugs.

 3
Author: Balamurugan Muthiah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-04 10:45:13

Parece como si por defecto las funciones de Google Guava son @Nullable por defecto - Estaba recibiendo errores de Findbugs indicando que "el resultado debe ser nonnull pero está marcado como nullable" cuando no había anotación. Agregar @Nonnull a la declaración de la función de la siguiente manera ayudó:

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

Y ahora Findbugs está feliz. Gracias a todos

 0
Author: Ben Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-28 09:39:54