Может ли кто-нибудь объяснить мне, как аннотации работают внутри Java?
Я знаю, как мы можем создавать собственные аннотации с помощью библиотеки java.lang.annotation в java. Но я до сих пор не понимаю, как это работает внутри, например, аннотация @Override.
Я буду очень благодарен, если кто-нибудь сможет это объяснить подробно.
java
annotations
Чираг Дасани
источник
источник
Ответы:
Первое основное различие между видами аннотаций заключается в том, используются ли они во время компиляции, а затем отбрасываются (как
@Override
) или помещаются в скомпилированный файл класса и доступны во время выполнения (как Spring@Component
). Это определяется политикой @Retention аннотации. Если вы пишете свою собственную аннотацию, вам нужно решить, будет ли она полезна во время выполнения (для автоконфигурации, возможно) или только во время компиляции (для проверки или генерации кода).При компиляции кода с аннотациями компилятор видит аннотацию так же, как он видит другие модификаторы исходных элементов, такие как модификаторы доступа (
public
/private
) илиfinal
. Когда он встречает аннотацию, он запускает обработчик аннотаций, который похож на класс подключаемого модуля, который говорит, что ему интересна конкретная аннотация. Обработчик аннотаций обычно использует Reflection API для проверки компилируемых элементов и может просто выполнять проверки, изменять их или генерировать новый код для компиляции.@Override
это пример первого; он использует Reflection API, чтобы убедиться, что он может найти совпадение для сигнатуры метода в одном из суперклассов, и использует,Messager
чтобы вызвать ошибку компиляции, если не может.Существует ряд руководств по написанию процессоров аннотаций; вот полезный . Посмотрите с помощью методов на в
Processor
интерфейсе для того, как компилятор вызывает процессор аннотаций; основная операция выполняется вprocess
методе, который вызывается каждый раз, когда компилятор видит элемент, имеющий соответствующую аннотацию.источник
Помимо того, что предлагали другие, я рекомендую вам написать индивидуальную аннотацию и ее обработчик с нуля, чтобы увидеть, как работает аннотация.
В моем собственном, например, я написал аннотацию, чтобы проверить, не перегружены ли методы во время компиляции.
Во-первых, создайте аннотацию с именем
Overload
. Эта аннотация применяется к методу, поэтому я аннотирую ее с помощью@Target(value=ElementType.METHOD)
package gearon.customAnnotation; import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target(value=ElementType.METHOD) public @interface Overload { }
Затем создайте соответствующий процессор для обработки элементов, аннотированных заданной аннотацией. Для метода, аннотированного пользователем
@Overload
, его подпись должна появляться более одного раза. Или печатается ошибка.package gearon.customAnnotation; import java.util.HashMap; import java.util.Map.Entry; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic.Kind; @SupportedAnnotationTypes("gearon.customAnnotation.Overload") public class OverloadProcessor extends AbstractProcessor{ @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { // TODO Auto-generated method stub HashMap<String, Integer> map = new HashMap<String, Integer>(); for(Element element : roundEnv.getElementsAnnotatedWith(Overload.class)){ String signature = element.getSimpleName().toString(); int count = map.containsKey(signature) ? map.get(signature) : 0; map.put(signature, ++count); } for(Entry<String, Integer> entry: map.entrySet()){ if(entry.getValue() == 1){ processingEnv.getMessager().printMessage(Kind.ERROR, "The method which signature is " + entry.getKey() + " has not been overloaded"); } } return true; } }
После упаковки аннотации и ее обработки в файл jar создайте класс
@Overload
и используйте javac.exe для его компиляции.import gearon.customAnnotation.Overload; public class OverloadTest { @Overload public static void foo(){ } @Overload public static void foo(String s){ } @Overload public static void nonOverloadedMethod(){ } }
Поскольку
nonOverloadedMethod()
фактически не было перегрузки, мы получим результат, как показано ниже:источник
OverloadProcessor::process
Почему в вашем классеentry.getValue() == 1
? Не нужно добавлять аннотацию к родительскому классу / интерфейсу, поэтомуroundEnv.getElementsAnnotatedWith(Overload.class)
не получится родительский класс / интерфейс, верно?Вот
@Override
: http://www.docjar.com/html/api/java/lang/Override.java.html .В нем нет ничего особенного, что отличает его от аннотации, которую вы можете написать самостоятельно. Интересные моменты находятся в потребителях аннотаций. В случае аннотации, например
@Override
, это может быть сам компилятор Java, инструмент статического анализа кода или ваша IDE.источник
@Override
(или другие стандартные аннотации).По сути, аннотации - это просто маркеры, которые считываются компилятором или приложением. В зависимости от их политики хранения они доступны только во время компиляции или доступны для чтения во время выполнения с использованием отражения.
Многие фреймворки используют сохранение во время выполнения, т.е. они рефлексивно проверяют, присутствуют ли некоторые аннотации в классе, методе, поле и т. Д., И что-то делают, если аннотация присутствует (или нет). Кроме того, члены аннотаций могут использоваться для передачи дополнительной информации.
источник
Перейдите по этой ссылке . Это даст подробный ответ на вашу проблему. Если мы сосредоточились на аннотациях
Java
, аннотации были введены в Java 5 и не относятся к Spring. Как правило, аннотации позволяют добавлять метаданные к классу, методу или переменной. Аннотация может интерпретироваться компилятором (например, аннотацией @Override) или фреймворком, таким как spring (например, аннотацией @Component).Вдобавок добавляю еще ссылки.
источник
Даже я искал ответ на тот же вопрос. приведенная ниже ссылка предоставила объединенный полезный материал, чтобы получить аннотации изнутри. https://dzone.com/articles/how-annotations-work-java Надеюсь, это поможет!
источник