Аннотации в Java

Java Annotations предоставляют информацию о коде. Аннотации Java не оказывают прямого влияния на код, который они аннотируют. В учебнике по аннотациям Java мы рассмотрим следующее;

  1. Встроенные аннотации Java
  2. Как написать пользовательскую аннотацию
  3. Использование аннотаций и как их парсить с использованием Reflection API.

Java Annotations

Java 1.5 ввёл аннотации, и сейчас они широко используются в Java EE-фреймворках, таких как Hibernate, Jersey и Spring. Аннотация Java – это метаданные о программе, встроенные в саму программу. Её можно разбирать с помощью инструмента разбора аннотаций или компилятора. Мы также можем указать доступность аннотации либо только во время компиляции, либо до времени выполнения. До появления аннотаций в Java метаданные программы были доступны через комментарии Java или через Javadoc, но аннотация предлагает больше возможностей. Метаданные аннотаций могут быть доступны и во время выполнения, и парсеры аннотаций могут использовать их для определения хода выполнения. Например, в веб-сервисе Jersey мы добавляем аннотацию PATH с URI-строкой к методу, и во время выполнения Jersey разбирает её, чтобы определить метод для вызова для данного шаблона URI.

Пользовательская аннотация Java

Создание пользовательской аннотации аналогично написанию интерфейса, за исключением того, что ключевое слово интерфейса предваряется символом _@_. Мы можем объявлять методы в аннотации. Давайте рассмотрим пример пользовательской аннотации на языке Java, а затем обсудим ее особенности и важные моменты.

package com.journaldev.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
	String author() default "Pankaj";
	String date();
	int revision() default 1;
	String comments();
}

Некоторые важные моменты касательно аннотаций в Java:

  1. Методы аннотации не могут иметь параметры.
  2. Типы возвращаемых значений методов аннотации ограничены примитивами, строкой, перечислениями, аннотациями или массивом из них.
  3. Методы аннотации в Java могут иметь значения по умолчанию.
  4. Аннотации могут иметь мета-аннотации, присоединенные к ним. Мета-аннотации используются для предоставления информации об аннотации.

Мета-аннотации в Java

Существует пять типов мета-аннотаций:

  1. @Documented – указывает, что элементы, использующие эту аннотацию, должны быть задокументированы javadoc и аналогичными инструментами. Этот тип следует использовать для аннотирования объявлений типов, аннотации которых влияют на использование аннотированных элементов их клиентами. Если объявление типа аннотировано как Documented, его аннотации становятся частью общедоступного API аннотированных элементов.
  2. @Target – указывает на типы элементов программы, к которым применим тип аннотации. Некоторые возможные значения: TYPE, METHOD, CONSTRUCTOR, FIELD и т. д. Если мета-аннотация Target отсутствует, то аннотацию можно использовать для любого элемента программы.
  3. @Inherited – указывает, что тип аннотации автоматически наследуется. Если пользователь запрашивает тип аннотации в объявлении класса, и в объявлении класса нет аннотации этого типа, то автоматически будет запрошена аннотация для суперкласса класса. Этот процесс будет повторяться до тех пор, пока не будет найдена аннотация для этого типа или не будет достигнут верх иерархии класса (Object).
  4. @Retention – указывает, как долго аннотации с аннотированным типом должны сохраняться. Принимает аргумент RetentionPolicy, чьи возможные значения: SOURCE, CLASS и RUNTIME
  5. @Repeatable – используется для указания того, что тип аннотации, которую он аннотирует, может повторяться.

Встроенные аннотации в Java

Java предоставляет пять встроенных аннотаций.

  1. @Override – Когда мы хотим переопределить метод суперкласса, мы должны использовать эту аннотацию, чтобы сообщить компилятору, что мы переопределяем метод. Таким образом, когда метод суперкласса удаляется или изменяется, компилятор выдаст сообщение об ошибке. Узнайте, почему мы всегда должны использовать аннотацию переопределения Java при переопределении метода.
  2. @Deprecated – когда мы хотим, чтобы компилятор знал, что метод устарел, мы должны использовать эту аннотацию. Java рекомендует, чтобы в javadoc мы предоставляли информацию о том, почему этот метод устарел, и что использовать в качестве альтернативы.
  3. @SuppressWarnings – Это просто чтобы сообщить компилятору игнорировать конкретные предупреждения, которые они производят, например, использование необработанных типов в обобщениях Java. Его политика удержания – SOURCE, и он отбрасывается компилятором.
  4. @FunctionalInterface – Эта аннотация была введена в Java 8, чтобы указать, что интерфейс предназначен быть функциональным интерфейсом.
  5. @SafeVarargs – Утверждение программиста о том, что тело аннотированного метода или конструктора не выполняет потенциально небезопасные операции с его параметром varargs.

Пример аннотаций Java

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

package com.journaldev.annotations;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

public class AnnotationExample {

	public static void main(String[] args) {
	}

	@Override
	@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1)
	public String toString() {
		return "Overriden toString method";
	}

	@Deprecated
	@MethodInfo(comments = "deprecated method", date = "Nov 17 2012")
	public static void oldMethod() {
		System.out.println("old method, don't use it.");
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10)
	public static void genericsTest() throws FileNotFoundException {
		List l = new ArrayList();
		l.add("abc");
		oldMethod();
	}

}

I believe above java annotation example is self-explanatory and showing the use of annotations in different cases.

Анализ аннотаций Java

Мы будем использовать Reflection для анализа аннотаций Java из класса. Обратите внимание, что политика удержания аннотации должна быть RUNTIME, иначе ее информация не будет доступна во время выполнения, и мы не сможем получить данные из нее.

package com.journaldev.annotations;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationParsing {

	public static void main(String[] args) {
		try {
			for (Method method : AnnotationParsing.class.getClassLoader()
					.loadClass(("com.journaldev.annotations.AnnotationExample")).getMethods()) {
				// проверяет, присутствует ли аннотация MethodInfo для метода
				if (method.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
					try {
						// перебирает все доступные аннотации в методе
						for (Annotation anno : method.getDeclaredAnnotations()) {
							System.out.println("Annotation in Method '" + method + "' : " + anno);
						}
						MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
						if (methodAnno.revision() == 1) {
							System.out.println("Method with revision no 1 = " + method);
						}

					} catch (Throwable ex) {
						ex.printStackTrace();
					}
				}
			}
		} catch (SecurityException | ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

}

Вывод программы:

Annotation in Method 'public java.lang.String com.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)

API Reflection очень мощное и широко используется в Java, фреймворках J2EE, таких как Spring, Hibernate, JUnit, ознакомьтесь с Reflection in Java. Вот и все для примера по аннотациям в Java, надеюсь, вы что-то усвоили из этого. Обновления по аннотациям Java:

  1. Спецификации Servlet 3.0 ввели использование аннотаций для конфигурации сервлетов и параметров инициализации, читайте больше на Учебнике по Java Servlet.
  2. Мы можем использовать аннотации в Struts 2 для конфигурации его классов действий и страниц результатов, проверьте рабочий пример на Примере приветствия мира Struts 2 с аннотациями.

Ссылка: Веб-сайт Oracle

Source:
https://www.digitalocean.com/community/tutorials/java-annotations