Может кто - нибудь объяснить , в ясной форме практических различий между java.lang.annotation.RetentionPolicy
константами SOURCE
, CLASS
и RUNTIME
?
Я также не совсем уверен, что означает фраза «сохранение аннотации».
Может кто - нибудь объяснить , в ясной форме практических различий между java.lang.annotation.RetentionPolicy
константами SOURCE
, CLASS
и RUNTIME
?
Я также не совсем уверен, что означает фраза «сохранение аннотации».
Ответы:
RetentionPolicy.SOURCE
: Сбросить во время компиляции. Эти аннотации не имеют никакого смысла после завершения компиляции, поэтому они не записываются в байт-код.
Пример:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
: Сбросить во время загрузки класса. Полезно при выполнении постобработки на уровне байт-кода. Несколько удивительно, это по умолчанию.
RetentionPolicy.RUNTIME
: Не выбрасывайте. Аннотация должна быть доступна для размышления во время выполнения. Пример:@Deprecated
Источник:
старый URL мертв, теперь
hunter_meta и заменен на hunter-meta-2-098036 . В случае, если даже это не работает, я загружаю изображение страницы.
Изображение (щелкните правой кнопкой мыши и выберите «Открыть изображение в новой вкладке / окне»)
RetentionPolicy.CLASS
apt
это устарело, обратитесь к этому docs.oracle.com/javase/7/docs/technotes/guides/apt/… . Для обнаружения аннотации с помощью рефлексии в Интернете есть несколько учебных пособий. Вы можете начать с изучения java.lang.Class::getAnno*
и аналогичных методов в java.lang.reflect.Method
и java.lang.reflect.Field
.
Согласно вашим комментариям о декомпиляции классов, вот как я думаю, что это должно работать:
RetentionPolicy.SOURCE
: Не появится в декомпилированном классе
RetentionPolicy.CLASS
: Появляются в декомпилированном классе, но не могут быть проверены во время выполнения с отражением getAnnotations()
RetentionPolicy.RUNTIME
: Появляются в декомпилированном классе и могут быть проверены во время выполнения с помощью getAnnotations()
Минимальный исполняемый пример
Уровень языка :
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;
}
Уровень байт-кода : при использовании javap
мы видим, что Retention.CLASS
аннотированный класс получает атрибут класса RuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
в то время как Retention.RUNTIME
аннотация получает атрибут класса RuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
и Runtime.SOURCE
аннотированный .class
не получает никаких аннотаций.
Примеры на GitHub для вас, чтобы играть с.
Политика хранения. Политика хранения определяет, в какой момент аннотация отклоняется. Это указывается с помощью встроенных аннотаций Java: @Retention
[About]
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.