A linha public static <T> java.util.@Nullable Optional<T> toJavaUtilé escrita assim, porque o estilo usual public static <T> @Nullable java.util.Optional<T> toJavaUtilé inválido. Isso é definido no JLS §9.7.4 :
É um erro em tempo de compilação se uma anotação do tipo T se aplicar a um tipo (ou qualquer parte de um tipo) em um contexto de tipo, e T for aplicável em contextos de tipo e a anotação não for admissível.
Por exemplo, suponha um tipo de anotação TA que seja meta-anotado com just @Target(ElementType.TYPE_USE). Os termos @TA java.lang.Objecte java.@TA lang.Objectsão ilegais porque o nome simples do qual @TA é o mais próximo é classificado como um nome de pacote. Por outro lado, java.lang.@TA Objecté legal.
A declaração de tipo de org.checkerframework.checker.nullness.qual@Nullableé:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
Então, isso se aplica a esta regra.
Que essa estrutura não interrompe a execução, pois o pacote java.utile o nome da classe Optionalforam divididos, pode ser visto quando analisamos o código compilado 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é uma classe local em que copiei o código do Guava, para obter um exemplo mínimo para descompilar / compilar)
Como você pode ver, a anotação não existe mais lá. É apenas um marcador para o compilador evitar um aviso quando o método retornar nulo (e uma dica para os leitores de código-fonte), mas ele não será incluído no código compilado.
Este erro do compilador também se aplica a variáveis como:
private @Nullable2 java.util.Optional<?> o;
Mas pode se tornar aceitável quando a anotação obtém adicionalmente o tipo de destino ElementType.FIELD, conforme escrito na mesma cláusula JLS:
Se o TA for adicionalmente meta-anotado @Target(ElementType.FIELD), o termo @TA java.lang.Objecté legal em locais que são tanto contextos de declaração quanto de tipo, como uma declaração de campo @TA java.lang.Object f;. Aqui, @TA é considerado aplicável à declaração de f (e não ao tipo java.lang.Object) porque TA é aplicável no contexto da declaração de campo.
Nullableque eles estão falando, parece haver nojavax.annotation, nãojava.util.