Alguém pode explicar de forma clara as diferenças práticas entre os java.lang.annotation.RetentionPolicy
constantes SOURCE
, CLASS
, e RUNTIME
?
Também não sei exatamente o que significa a frase "retendo anotação".
Alguém pode explicar de forma clara as diferenças práticas entre os java.lang.annotation.RetentionPolicy
constantes SOURCE
, CLASS
, e RUNTIME
?
Também não sei exatamente o que significa a frase "retendo anotação".
Respostas:
RetentionPolicy.SOURCE
: Descartar durante a compilação. Essas anotações não fazem sentido após a compilação ser concluída, portanto, elas não são gravadas no bytecode.
Exemplo:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
: Descartar durante o carregamento da classe. Útil ao executar o pós-processamento no nível de bytecode. Surpreendentemente, esse é o padrão.
RetentionPolicy.RUNTIME
: Não descarte. A anotação deve estar disponível para reflexão no tempo de execução. Exemplo:@Deprecated
Origem:
o URL antigo está morto agora
hunter_meta e substituído por hunter-meta-2-098036 . Caso isso aconteça, estou carregando a imagem da página.
Imagem (Clique com o botão direito do mouse e selecione 'Abrir imagem em uma nova guia / janela')
RetentionPolicy.CLASS
apt
sido descontinuado, consulte este documentos.oracle.com/javase/7/docs/technotes/guides/apt/… . Para descobrir anotações usando reflexão, existem vários tutoriais na Internet. Você pode começar examinando java.lang.Class::getAnno*
métodos semelhantes em java.lang.reflect.Method
e java.lang.reflect.Field
.
De acordo com seus comentários sobre a descompilação de classes, aqui está como eu acho que deve funcionar:
RetentionPolicy.SOURCE
: Não aparecerá na classe descompilada
RetentionPolicy.CLASS
: Aparece na classe descompilada, mas não pode ser inspecionada em tempo de execução com reflexão com getAnnotations()
RetentionPolicy.RUNTIME
: Aparecem na classe descompilada e podem ser inspecionados em tempo de execução com reflexão com getAnnotations()
Exemplo mínimo executável
Nível de idioma :
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.SOURCE)
@interface RetentionSource {}
@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}
@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}
public static void main(String[] args) {
@RetentionSource
class B {}
assert B.class.getAnnotations().length == 0;
@RetentionClass
class C {}
assert C.class.getAnnotations().length == 0;
@RetentionRuntime
class D {}
assert D.class.getAnnotations().length == 1;
}
Nível de bytecode : usando javap
, observamos que a Retention.CLASS
classe anotada recebe um atributo de classe RuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
enquanto a Retention.RUNTIME
anotação obtém um atributo de classe RuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
e o Runtime.SOURCE
anotado .class
não recebe nenhuma anotação.
Exemplos no GitHub para você brincar.
Política de retenção: uma política de retenção determina em que momento uma anotação é descartada. É especificado usando as anotações internas do Java: @Retention
[Sobre]
1.SOURCE: annotation retained only in the source file and is discarded
during compilation.
2.CLASS: annotation stored in the .class file during compilation,
not available in the run time.
3.RUNTIME: annotation stored in the .class file and available in the run time.