L’interface com.google.common.base.Function
(de Google Guava ) définit apply
comme:
@Nullable T apply(@Nullable F input);
La méthode a la note javadoc suivante:
@throws NullPointerException if {@code input} is null and this function does not accept null arguments
.
FindBugs se plaint de mon implémentation de 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;
}
}
avec un priorité élevée warning:
NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE, priorité: élevée
l'entrée doit être non vide mais est marquée comme nullable
Ce paramètre est toujours utilisé d'une manière qui exige qu'il soit non nul, mais il est explicitement annoté comme étant Nullable. L'utilisation du paramètre ou de l'annotation est incorrecte.
Ma fonction ne prend pas en charge les entrées null
et une exception est levée si tel est le cas. Si je comprends bien, FindBugs considère cela comme une exigence pour non-null.
Pour moi, cela ressemble à une contradiction: l'entrée est @Nullable mais la méthode @throws NullPointerException lorsqu'elle est nulle. Est-ce que je manque quelque chose?
Le seul moyen de me débarrasser de l'avertissement que je peux voir est la suppression manuelle. (Le code de goyave est hors de mon contrôle, évidemment).
Qui se trompe dans l'utilisation de l'annotation @Nullable, FindBugs, Guava ou moi-même?
Votre implémentation est fausse;)
Fondamentalement docs dit (je vais paraphraser et souligner):
@throws NullPointerException
siinput
est null et la mise en oeuvre concrète de la fonction n'accepte pas les arguments nuls
En implémentant votre fonction, vous devez décider si elle accepte les valeurs NULL ou non. Dans le premier cas:
private static final class Example implements Function<MyBean, String> {
@Override
@Nullable
public String apply(@Nullable MyBean input) {
return input == null ? null : input.field;
}
}
En second cas:
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;
}
}
Dans les deux exemples, renvoyer null est autorisé.
EDIT:
Notez que Guava utilise @javax.annotation.ParametersAreNonnullByDefault
sur tous les packages. Par conséquent, si @Nullable
est présent, cela signifie "suspendre le @Nonnull
global et autoriser les valeurs NULL ici", sinon, "NULL interdit ici".
Cela dit, vous voudrez peut-être utiliser l'annotation @Nonnull
sur votre argument ou @ParametersAreNonnullByDefault
dans le package pour indiquer que l'argument de FindBugs ne peut pas être null.
EDIT 2:
Il s'avère que cette affaire est connue , voir le commentaire n ° 3 (de Kevin Bourrillion, développeur principal de Guava, à propos de sa conversation avec Bill Pugh, responsable de Findbugs):
Ma référence était une série de conversations en personne avec Bill Pugh. Il a affirmé sans ambiguïté que
@Nullable
signifie uniquement que certains sous-types Pourraient accepter null. Et cela semble être corroboré par findbugs pour nous - notre code passe assez bien les contrôles de nullabilité (bien que nous Devrions vérifier à nouveau depuis que cette fonction a été modifiée).
Le marquage du paramètre @Nonnull
résout le problème de findbugs.
Il semble que, par défaut, les fonctions de Google Guava soient @Nullable par défaut. Des erreurs Findbugs survenues m'indiquaient que "le résultat doit être non nul mais marqué comme nul", en l'absence d'annotation. L'ajout de @Nonnull à la déclaration de fonction de la manière suivante a aidé:
new Function<Object, Object>() {
@Nonnull
public Object apply(@Nonnull Object object) {
et maintenant Findbugs est heureux. Merci a tous