Може хто - небудь пояснити , в ясній формі практичних відмінностей між 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 замінена на мисливець-мета-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
[Про]
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.