2012-09-14 5 views
33

La interfaz com.google.common.base.Function (de Google Guava) define apply como:entrada @Nullable en interfaz de la función Google Guava desencadena FindBugs advertencia

@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 un de alta prioridad advertencia:

NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE, Prioridad: Alta

de entrada debe ser no nulo, pero está marcado como nulable

Este parámetro siempre se usa de una manera que requiere que sea no nulo, pero el parámetro se anota explícitamente como anulable. O el uso del parámetro o la anotación es incorrecto.

Mi función no admite null entradas y se produce una excepción si ese es el caso. Si entiendo correctamente, FindBugs lo trata como un requisito para no nulo.

Para mí, parece una contradicción: la entrada es @Nullable pero el método @throws NullPointerException cuando es nulo. ¿Me estoy perdiendo de 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 no sobre el uso de @Nullable annotation, FindBugs, Guava o yo mismo?

+4

Estás diciendo que aceptarás nulo en la firma, y ​​luego estás * rechazando * un valor nulo en el cuerpo. Parece que no entendiste el propósito de '@ Nullable'. –

+4

La única razón por la que agregué '@ Nullable' para el parámetro de entrada es que es lo que define la interfaz' Function'. De todos modos, eliminé la anotación '@ Nullable' del parámetro como se sugirió @Xaerxess, pero FindBugs sigue quejándose. – vitaly

Respuesta

28

Su aplicación está mal;)

Básicamente dice docs (Voy a parafrasear y subrayo):

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

Al implementar su función, debe decidir si acepta nulos o no. En 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 segundo caso: se permite

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 que regresan nulo.

EDIT:

Tenga en cuenta que la guayaba utiliza @javax.annotation.ParametersAreNonnullByDefault en todos los paquetes, por lo tanto, si está presente @Nullable que significa "suspender mundial @Nonnull y permiten nulos aquí", y si no que significa "nulos prohibidos aquí".

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

EDIT 2:

Resulta que this case is known issue, ver el comentario # 3 (de dev ventaja de guayaba Kevin Bourrillion, sobre su conversación con Bill Pugh, plomo Findbugs'):

Mi referencia era una serie de conversaciones en persona con Bill Pugh. Afirmó inequívocamente que @Nullable significa que algunos subtipos podrían aceptar nulo. Y esto parece corroborado por findbugs para nosotros: nuestro código pasa las comprobaciones de nullability bastante limpiamente (aunque nosotros deberíamos volver a verificarlo desde que se realizó este cambio de función en particular).

+0

¿Qué me hace preguntarme si está bien eliminar las anotaciones especificadas por la interfaz en la implementación? – vitaly

+1

No los elimine de la interfaz, lo agrega a su implementación. Si 'Function' le permite usar null como argumento, eso no significa que tendrá que permitir null en su impl, tal como lo indica el contrato' Function'. – Xaerxess

+4

La anotación ya está especificada por la interfaz del marco y no puedo (y no tengo la intención de) eliminarla si procede de allí. El único código que puedo editar es mi propio código (= implementación). Quité las anotaciones @Nullable de mi implementación, pero FindBugs sigue quejándose. – vitaly

3

Al marcar el parámetro @Nonnull se resuelve el problema de los findbugs.

0

Parece que, por defecto, las funciones de Google Guava son @Nullable por defecto - Obtuve errores de Findbugs que indicaban que "el resultado debe ser no nulo pero marcado como anulable" cuando no había anotación. Agregar @Nonnull a la declaración de función de la siguiente manera ayudó:

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

y ahora Findbugs is happy. Gracias a todos

Cuestiones relacionadas