Estou lendo o código do Goiaba, onde encontrei a anotação java.util.@Nullable
em algum código. Eu sei o significado de @Nullable
, mas eu não entendo este. Em particular, não consigo encontrar uma classe chamada Nullable
no pacote java.util
. Por favor, alguém me diga qual é o significado disso java.util.@Nullable
:
public static <T> java.util.@Nullable Optional<T> toJavaUtil(
@Nullable Optional<T> googleOptional) {
return googleOptional == null ? null : googleOptional.toJavaUtil();
}
Nullable
que eles estão falando, parece haver nojavax.annotation
, nãojava.util
.public static <T> @Nullable java.util.Optional<T> toJavaUtil
, mas o Java simplesmente não permite que você escreva dessa maneira?public static <T> @Nullable java.util.Optional<T> toJavaUtil
realmente não é possível, mas não há razão para usar o FQNOptional
quando a importação já existe.Optional
escopo lá.@Nullable java.util.List The correct Java syntax to write an annotation on a fully-qualified type name is to put the annotation on the simple name part, as in java.util.@Nullable List. But, it’s usually better to add import java.util.List to your source file, so that you can just write @Nullable List.
Respostas:
A linha
public static <T> java.util.@Nullable Optional<T> toJavaUtil
é escrita assim, porque o estilo usualpublic static <T> @Nullable java.util.Optional<T> toJavaUtil
é inválido. Isso é definido no JLS §9.7.4 :A declaração de tipo de
org.checkerframework.checker.nullness.qual@Nullable
é:Então, isso se aplica a esta regra.
Que essa estrutura não interrompe a execução, pois o pacote
java.util
e o nome da classeOptional
foram divididos, pode ser visto quando analisamos o código compilado usandojavap -c [compiled class name]
:(
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:
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:fonte
Ao usar anotações, esta é a sintaxe usada quando você deseja escrever um nome completo para o tipo, em vez de adicionar uma declaração de importação.
Citando o manual da estrutura do verificador :
Também é mencionado na página 2 da especificação JSR308, que pode ser baixada aqui . Diz:
fonte
O estranho aqui é realmente a sintaxe desconhecida para aplicar uma
ElementType.TYPE_USE
anotação segmentada. Se você verificar os documentos do Nullable , verá o destino desconhecido:Essa anotação é usada imediatamente antes do nome simples do tipo anotado, como nos dois itens a seguir:
Como eu não sabia o que era esse tipo de destino, depois de uma leitura rápida, cheguei a este exemplo simples, que coleta metadados de tipo de retorno usando uma anotação com esse destino:
E processou usando:
Tenho certeza de que muitas estruturas úteis, como o checkerframework, fazem o uso mais apropriado de
ElementType.TYPE_USE
fonte