Рубрики
Без рубрики

Изменение Параметров Аннотации Во Время Выполнения

Узнайте, как изменять параметры аннотаций во время выполнения с помощью отражения в Java.

Автор оригинала: baeldung.

1. Обзор

Аннотации , форма метаданных, которую вы можете добавить в код Java. Эти аннотации могут быть обработаны во время компиляции и встроены в файлы классов или могут быть сохранены и доступны во время выполнения с помощью Отражения .

В этой статье мы обсудим, как изменить аннотацию значение во время выполнения с помощью Отражения . В этом примере мы будем использовать аннотации уровня класса.

2. Аннотация

Java позволяет создавать новые аннотации используя существующие. В простейшей форме аннотация представляется в виде @ символ, за которым следует название аннотации:

@Override

Давайте создадим нашу собственную аннотацию Более значительный :

@Retention(RetentionPolicy.RUNTIME)
public @interface Greeter {    
    public String greet() default ""; 
}

Теперь мы создадим класс Java Приветствия , который использует аннотацию уровня класса |:

@Greeter(greet="Good morning")
public class Greetings {}

Теперь мы получим доступ к значению аннотации с помощью отражения. Класс Java Класс предоставляет метод getAnnotation для доступа к аннотациям класса:

Greeter greetings = Greetings.class.getAnnotation(Greeter.class);
System.out.println("Hello there, " + greetings.greet() + " !!");

3. Измените Аннотацию

Класс Java Класс поддерживает карту для управления аннотациями – Аннотации класс в качестве ключей и Аннотации объект в качестве значения:

Map, Annotation> map;

Мы обновим эту карту, чтобы изменить аннотацию во время выполнения. Подход к доступу к этой карте отличается в различных реализациях JDK. Мы обсудим это для JDK7 и JDK8.

3.1. Реализация JDK 7

Класс Java Класс имеет поле |/аннотации . Поскольку это закрытое поле, чтобы получить к нему доступ, мы должны установить доступность поля в true . Java предоставляет метод getDeclaredField для доступа к любому полю по его имени:

Field annotations = Class.class.getDeclaredField(ANNOTATIONS);
annotations.setAccessible(true);

Теперь давайте получим доступ к карте аннотаций для класса Встречающий :

 Map, Annotation> map = annotations.get(targetClass);

Теперь это карта, которая содержит информацию обо всех аннотациях и их объекте значения. Мы хотим изменить Более значительный значение аннотации, которое мы можем получить, обновив объект аннотации Более значительный класс:

map.put(targetAnnotation, targetValue);

3.2. Реализация JDK 8

Реализации Java 8 хранят аннотации информацию внутри класса Данные аннотации . Мы можем получить доступ к этому объекту с помощью метода данные аннотации . Мы установим доступность для данных аннотации метода в true , поскольку это частный метод:

Method method = Class.class.getDeclaredMethod(ANNOTATION_METHOD, null);
method.setAccessible(true);

Теперь мы можем получить доступ аннотации поле. Поскольку это поле также является закрытым полем, мы установим доступность для истинный :

Field annotations = annotationData.getClass().getDeclaredField(ANNOTATIONS);
annotations.setAccessible(true);

В этом поле есть карта кэша аннотаций, в которой хранятся класс аннотаций и объект значения. Давайте изменим это:

Map, Annotation> map = annotations.get(annotationData); 
map.put(targetAnnotation, targetValue);

4. Применение

Давайте возьмем этот пример:

Greeter greetings = Greetings.class.getAnnotation(Greeter.class);
System.err.println("Hello there, " + greetings.greet() + " !!");

Это будет приветствие “Доброе утро”, поскольку именно это значение мы предоставили аннотации.
Теперь мы создадим еще один объект Большего
типа со значением “Добрый вечер”:

Greeter targetValue = new DynamicGreeter("Good evening");

Давайте обновим карту аннотаций новым значением:

alterAnnotationValueJDK8(Greetings.class, Greeter.class, targetValue);

Давайте еще раз проверим значение приветствия:

greetings = Greetings.class.getAnnotation(Greeter.class);
System.err.println("Hello there, " + greetings.greet() + " !!");

Он поприветствует вас как “Добрый вечер”.

5. Заключение

Реализации Java используют два поля данных для хранения данных аннотаций: аннотации , Заявленные примечания . Разница между этими двумя: сначала также сохраняются аннотации из родительских классов, а затем сохраняются только для текущего класса.

Поскольку реализация getAnnotation отличается в JDK 7 и JDK 8, мы используем здесь аннотации карту полей для простоты.

И, как всегда, исходный код реализации доступен на Github .