La riga public static <T> java.util.@Nullable Optional<T> toJavaUtilè scritta in questo modo, perché il solito stile public static <T> @Nullable java.util.Optional<T> toJavaUtilnon è valido. Questo è definito nel JLS §9.7.4 :
È un errore in fase di compilazione se un'annotazione di tipo T si applica a un tipo (o a qualsiasi parte di un tipo) in un contesto di tipo e T è applicabile in contesti di tipo e l'annotazione non è ammissibile.
Ad esempio, supponi un tipo di annotazione TA che è meta-annotato con just @Target(ElementType.TYPE_USE). I termini @TA java.lang.Objecte java.@TA lang.Objectsono illegali perché il nome semplice a cui @TA è più vicino è classificato come nome del pacchetto. D'altra parte, java.lang.@TA Objectè legale.
La dichiarazione del tipo di org.checkerframework.checker.nullness.qual@Nullableè:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
Quindi si applica a questa regola.
Che questa struttura non interrompa l'esecuzione, dal momento che il java.utilnome del pacchetto e della classe Optionalsono stati divisi, si può vedere osservando il codice compilato usando 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.Optionalè una classe locale in cui ho copiato il codice Guava, per ottenere un esempio minimo di de- / compilare)
Come puoi vedere, l'annotazione non esiste più lì. È solo un indicatore per il compilatore per impedire un avviso quando il metodo restituisce null (e un suggerimento per i lettori di codice sorgente), ma non verrà incluso nel codice compilato.
Questo errore del compilatore si applica anche a variabili come:
private @Nullable2 java.util.Optional<?> o;
Ma può diventare accettabile quando l'annotazione ottiene anche il tipo di destinazione ElementType.FIELD, come scritto nella stessa clausola JLS:
Se TA è inoltre meta-annotato con @Target(ElementType.FIELD), allora il termine @TA java.lang.Objectè legale in posizioni che sono sia contesti di dichiarazione che di tipo, come una dichiarazione di campo @TA java.lang.Object f;. In questo caso, @TA è considerato applicabile alla dichiarazione di f (e non al tipo java.lang.Object) perché TA è applicabile nel contesto della dichiarazione di campo.
Nullablestanno parlando ci sembra essere injavax.annotation, non èjava.util.