La ligne public static <T> java.util.@Nullable Optional<T> toJavaUtilest écrite comme ceci, car le style habituel public static <T> @Nullable java.util.Optional<T> toJavaUtiln'est pas valide. Ceci est défini dans le JLS §9.7.4 :
Il s'agit d'une erreur au moment de la compilation si une annotation de type T s'applique à un type (ou à toute partie d'un type) dans un contexte de type, et T est applicable dans des contextes de type, et l'annotation n'est pas admissible.
Par exemple, supposons un type d'annotation TA qui est méta-annoté avec just @Target(ElementType.TYPE_USE). Les termes @TA java.lang.Objectet java.@TA lang.Objectsont illégaux car le nom simple dont @TA est le plus proche est classé comme nom de package. D'un autre côté, java.lang.@TA Objectc'est légal.
La déclaration de type de org.checkerframework.checker.nullness.qual@Nullableest:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
Cela s'applique donc à cette règle.
Le fait que cette structure ne casse pas l'exécution, puisque le nom du package java.utilet de la classe Optionalont été séparés, peut être vu lorsque nous regardons le code compilé en utilisant javap -c [compiled class name]:
class just.a.test.Main {
just.a.test.Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static <T> java.util.Optional<T> toJavaUtil(blub.Optional<T>);
Code:
0: aload_0
1: ifnonnull 8
4: aconst_null
5: goto 12
8: aload_0
9: invokevirtual #2 // Method blub/Optional.toJavaUtil:()Ljava/util/Optional;
12: areturn
}
( blub.Optionalest une classe locale dans laquelle j'ai copié le code de la goyave, afin d'obtenir un exemple minimal à dé / compiler)
Comme vous pouvez le voir, l'annotation n'existe plus. Ce n'est qu'un marqueur pour le compilateur pour empêcher un avertissement lorsque la méthode retourne null (et un indice pour les lecteurs de code source), mais il ne sera pas inclus dans le code compilé.
Cette erreur de compilation s'applique également aux variables telles que:
private @Nullable2 java.util.Optional<?> o;
Mais peut devenir acceptable lorsque l'annotation obtient en outre le type cible ElementType.FIELD, comme écrit dans la même clause JLS:
Si TA est en outre méta-annoté avec @Target(ElementType.FIELD), alors le terme @TA java.lang.Objectest légal dans les emplacements qui sont à la fois des contextes de déclaration et de type, comme une déclaration de champ @TA java.lang.Object f;. Ici, @TA est réputé s'appliquer à la déclaration de f (et non au type java.lang.Object) car TA est applicable dans le contexte de déclaration de champ.
Nullableils parlent semble y êtrejavax.annotation, nonjava.util.