2012-09-14 10 views
33

L'interfaccia com.google.common.base.Function (da Google Guava) definisce apply come:ingresso @Nullable in funzione di interfaccia Google Guava innesca FindBugs avvertimento

@Nullable T apply(@Nullable F input);

Il metodo ha il seguente nota javadoc:

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

FindBugs lamenta mia implementazione della funzione:

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 ad alta priorità avvertimento:

NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE, Priorità: alta

ingresso deve essere non nullo, ma è segnato come nullable

Questo parametro viene sempre utilizzato in un modo che richiede che non sia null, ma il parametro è annotato esplicitamente come Nullable. O l'uso del parametro o dell'annotazione è sbagliato.

La mia funzione non supporta null ingressi e viene generata un'eccezione se questo è il caso. Se ho capito bene, FindBugs considera questo come un requisito per non null.

Per me sembra una contraddizione: l'input è @Nullable ma il metodo @throws NullPointerException quando è nullo. Mi sto perdendo qualcosa?

L'unico modo per eliminare l'avviso che è possibile vedere è la soppressione manuale. (Il codice Guava è fuori dal mio controllo, ovviamente).

Chi ha torto sull'utilizzo dell'annotazione @Nullable, di FindBugs, di Guava o di me?

+4

Stai dicendo che accetterai nulla nella firma, e quindi si sta rifiutando * * un valore nullo nel corpo. Sembra che tu abbia frainteso lo scopo di '@ Nullable'. –

+4

L'unico motivo per cui ho aggiunto '@ Nullable' per i parametri di input è che è ciò che definisce l'interfaccia' Function'. Comunque, ho rimosso l'annotazione di '@ Nullable' dal parametro come suggerito da @Xaerxess ma FindBugs continua a lamentarsi. – vitaly

risposta

28

L'implementazione è sbagliata;)

Fondamentalmente docs dice (io parafrasi e sottolineo):

@throws NullPointerException se input è nullo e l'attuazione concreta funzione di non accetta argomenti nulli

Implementando la funzione è necessario decidere se accetta valori nulli o meno. Nel primo caso:

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

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

In entrambi gli esempi di ritorno nullo è consentito.

EDIT:

noti che Guava utilizza @javax.annotation.ParametersAreNonnullByDefault su tutti i pacchetti, quindi se @Nullable è presente significa "sospendono globale @Nonnull e permettono null qui" e se non significa "null proibite qui".

Detto questo, è possibile utilizzare l'annotazione @Nonnull nell'argomento o @ParametersAreNonnullByDefault nel pacchetto per indicare che l'argomento della funzione FindBugs non può essere nullo.

EDIT 2:

Risulta this case is known issue, vedi commento # 3 (da dev vantaggio di Guava Kevin Bourrillion, circa la sua conversazione con Bill Pugh, piombo Findbugs'):

Il mio riferimento era una serie di conversazioni di persona con Bill Pugh. Egli ha affermato in modo inequivocabile che @Nullable significa solo che alcuni sottotipi potrebbero accettare nulla. E questo sembra essere confermato da findbugs per noi - il nostro codice passa i controlli nullability abbastanza pulito (anche se abbiamo dovremmo controllare di nuovo dal momento che questo cambiamento particolare funzione è stato fatto).

+0

Che mi viene da chiedersi se è corretto rimuovere le annotazioni specificate dall'interfaccia nell'implementazione? – vitaly

+1

Non li rimuovi dall'interfaccia, aggiungi la tua implementazione. Se 'Funzione' ti permette di usare null come argomento che non significa che devi consentire null nel tuo impl, proprio come afferma il contratto' Function'. – Xaerxess

+4

L'annotazione è già specificata dall'interfaccia framework e non posso (e non intendo) rimuovere se da lì. L'unico codice che posso modificare è il mio codice (= implementazione). Ho rimosso le annotazioni @Nullable dalla mia implementazione ma FindBugs continua a lamentarsi. – vitaly

3

Contrassegnare il parametro @Nonnull risolve il problema da findbugs.

0

Sembra che per impostazione predefinita le funzioni di Google Guava siano @Nullable per impostazione predefinita. Ricevevo gli errori di Findbug affermando che "il risultato deve essere non nullo ma è contrassegnato come annullabile" quando non c'erano annotazioni. Aggiungendo @Nonnull alla dichiarazione di funzione nel seguente modo aiutato:

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

e ora Findbugs è felice. Grazie a tutti

Problemi correlati