stringtranslate.com

Java-аннотация

В языке программирования Java аннотация это форма синтаксических метаданных , которые можно добавлять в исходный код Java . [1] Классы , методы , переменные , параметры и пакеты Java могут быть аннотированы. Подобно тегам Javadoc , аннотации Java можно читать из исходных файлов. В отличие от тегов Javadoc , аннотации Java также можно встраивать в файлы классов Java, созданные компилятором Java, и читать из них. Это позволяет виртуальной машине Java сохранять аннотации во время выполнения и читать их через отражение . [2] Можно создавать метааннотации из существующих в Java. [3]

История

Платформа Java имеет различные механизмы аннотаций ad-hoc , например, transientмодификатор или @Deprecatedтег javadoc. Запрос спецификации Java JSR-175 представил средство аннотации общего назначения (также известное как метаданные ) в Java Community Process в 2002 году; оно получило одобрение в сентябре 2004 года. [4]

Аннотации стали доступны в самом языке, начиная с версии 1.5 Java Development Kit (JDK). aptИнструмент предоставлял временный интерфейс для обработки аннотаций во время компиляции в JDK версии 1.5; JSR-269 формализовал это, и он был интегрирован в компилятор javac в версии 1.6.

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

Java определяет набор аннотаций, встроенных в язык. Из семи стандартных аннотаций три являются частью java.lang , а остальные четыре импортируются из java.lang.annotation. [5] [6]

Аннотации, применяемые к коду Java:

Аннотации, применяемые к другим аннотациям (также известные как «метааннотации»):

Начиная с Java 7 в язык были добавлены три дополнительные аннотации.

Пример

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

Этот пример демонстрирует использование аннотации @Override. Он предписывает компилятору проверять родительские классы на предмет соответствия методов. В этом случае генерируется ошибка, поскольку gettype()метод класса Cat на самом деле не переопределяет getType()класс Animal, как это требуется, из-за несоответствия case . Если бы аннотация отсутствовала, в классе Cat был бы создан @Overrideновый метод name .gettype()

публичный класс Животное { публичный void speak () { }         public String getType () { return "Общее животное" ; } }      public class Cat extends Animal { @Override public void speak () { // Это хорошее переопределение. System . out . println ( "Мяу." ); }              @Override public String gettype () { // Ошибка компиляции из-за опечатки: должно быть getType(), а не gettype(). return "Cat" ; } }        

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

Объявления типа аннотации похожи на обычные объявления интерфейса. Знак @ предшествует ключевому слову "interface".

 // @Twizzle — это аннотация к методу toggle(). @Twizzle public void toggle () { }       // Объявляет аннотацию Twizzle. public @interface Twizzle { }     

Аннотации могут включать набор пар ключ-значение, которые моделируются как методы типа аннотации. Каждое объявление метода определяет элемент типа аннотации. Объявления методов не должны иметь никаких параметров или предложения throws. Типы возвращаемых значений ограничены примитивами , строками , классами, перечислениями , аннотациями и массивами предыдущих типов. Методы могут иметь значения по умолчанию .

 // То же, что: @Edible(value = true) @Edible ( true ) Элемент item = new Carrot ();       public @interface Edible { логическое значение () по умолчанию false ; }         @Author ( first = "Oompah" , last = "Loompah" ) Книга книга = новая Книга ();           public @interface Author { Первая строка (); Последняя строка (); }        

Сами аннотации могут быть аннотированы для указания того, где и когда их можно использовать:

 @Retention ( RetentionPolicy . RUNTIME ) // Сделать эту аннотацию доступной во время выполнения через отражение. @Target ({ ElementType . METHOD }) // Эту аннотацию можно применять только к методам класса. public @interface Tweezable { }        

Компилятор резервирует набор специальных аннотаций (включая @Deprecated, @Overrideи @SuppressWarnings) для синтаксических целей.

Аннотации часто используются фреймворками как способ удобного применения поведения к определяемым пользователем классам и методам, которые в противном случае должны быть объявлены во внешнем источнике (например, в файле конфигурации XML) или программно (с вызовами API). Ниже, например, представлен аннотированный класс данных JPA :

@Entity // Объявляет это компонентом сущности @Table ( name = "people" ) // Сопоставляет компонент с таблицей SQL "people" public class Person implements Serializable { @Id // Сопоставляет это со столбцом первичного ключа. @GeneratedValue ( strategy = GenerationType . AUTO ) // База данных сгенерирует новые первичные ключи, а не мы. private Integer id ;                   @Column ( length = 32 ) // Усечение значений столбцов до 32 символов. private String name ;       public Integer getId () { return id ; }       public void setId ( Integer id ) { this.id = id ; }         public String getName () { return name ; }       public void setName ( имя строки ) { this.name = имя ; } }        

Аннотации не являются вызовами методов и сами по себе ничего не делают. Вместо этого объект класса передается реализации JPA во время выполнения , которая затем извлекает аннотации для генерации объектно-реляционного отображения .

Полный пример приведен ниже:

пакет com.annotation ; 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 @Retention ( RetentionPolicy.RUNTIME ) @Target ( { ElementType.TYPE , ElementType.METHOD , ElementType.CONSTRUCTOR , ElementType.ANNOTATION_TYPE , ElementType.PACKAGE , ElementType.FIELD , ElementType.LOCAL_VARIABLE } ) @Inherited  public @interface Незавершенный { public enum Приоритет { НИЗКИЙ , СРЕДНИЙ , ВЫСОКИЙ } String value (); String [] changedBy () по умолчанию "" ; String [] lastChangedBy () по умолчанию "" ; Приоритет priority () по умолчанию Приоритет . СРЕДНИЙ ; String createdBy () по умолчанию "Джеймс Гослинг" ; String lastChanged () по умолчанию "2011-07-08" ; }                                 
пакет com.annotation ; public @interface UnderConstruction { String owner () по умолчанию "Патрик Нотон" ; String value () по умолчанию "Объект находится в стадии строительства." ; String createdBy () по умолчанию "Майк Шеридан" ; String lastChanged () по умолчанию "2011-07-08" ; }                   
пакет com.validators ; импорт javax.faces.application.FacesMessage ; импорт javax.faces.component.UIComponent ; импорт javax.faces.context.FacesContext ; импорт javax.faces.validator.Validator ; импорт javax.faces.validator.ValidatorException ;     import com.annotation.UnderConstruction ; import com.annotation.Unfinished ; import com.annotation.Unfinished.Priority ; import com.util.Util ;    @UnderConstruction ( owner = "Jon Doe" ) public class DateValidator implements Validator { public void validate ( контекст FacesContext , компонент UIComponent , значение Object ) throws ValidatorException { String date = ( String ) value ; String errorLabel = "Введите допустимую дату." ; if ( ! component.getAttributes ( ). isEmpty ()) { errorLabel = ( String ) component.getAttributes ( ) . get ( " errordisplayval " ); }                                  если ( ! Util . validateAGivenDate ( date )) { @Unfinished ( changedBy = "Steve" , value = "добавлять сообщение в контекст или нет, подтвердить" , priority = Priority . HIGH ) FacesMessage message = new FacesMessage (); message . setSeverity ( FacesMessage . SEVERITY_ERROR ); message . setSummary ( errorLabel ); message . setDetail ( errorLabel ); throw new ValidatorException ( message ); } } }                         

Обработка

При компиляции исходного кода Java аннотации могут обрабатываться подключаемыми модулями компилятора, называемыми процессорами аннотаций. Процессоры могут создавать информационные сообщения или создавать дополнительные исходные файлы или ресурсы Java, которые в свою очередь могут быть скомпилированы и обработаны. Однако процессоры аннотаций не могут изменять сам аннотированный код. (Модификации кода могут быть реализованы с использованием методов, выходящих за рамки спецификации языка Java.) Компилятор Java условно сохраняет метаданные аннотаций в файлах классов, если аннотация имеет RetentionPolicyили CLASS. RUNTIMEПозже JVM или другие программы могут искать метаданные, чтобы определить, как взаимодействовать с элементами программы или изменять их поведение.

В дополнение к обработке аннотации с помощью процессора аннотаций, программист Java может написать свой собственный код, который использует отражение для обработки аннотации. Java SE 5 поддерживает новый интерфейс, который определен в java.lang.reflectпакете. Этот пакет содержит интерфейс AnnotatedElement, который реализуется классами отражения Java, включая Class, Constructor, Field, Method, и Package. Реализации этого интерфейса используются для представления аннотированного элемента программы, которая в данный момент выполняется в виртуальной машине Java. Этот интерфейс позволяет считывать аннотации рефлексивно.

Интерфейс AnnotatedElementпредоставляет доступ к аннотациям, имеющим RUNTIMEсохранение. Этот доступ предоставляется методами getAnnotation, getAnnotationsи isAnnotationPresent. Поскольку типы аннотаций компилируются и сохраняются в файлах байт-кода, как и классы, аннотации, возвращаемые этими методами, можно запрашивать так же, как и любой обычный объект Java. Полный пример обработки аннотации приведен ниже:

импорт java.lang.annotation.Retention ;  // Это аннотация для обработки // Значение по умолчанию для Target — все элементы Java // Изменить политику хранения на RUNTIME (по умолчанию CLASS) @Retention ( RetentionPolicy . RUNTIME ) public @interface TypeHeader { // Значение по умолчанию, указанное для атрибута разработчика String developer () default "Unknown" ; String lastModified (); String [] teamMembers (); int meaningOfLife (); }               
// Это аннотация, применяемая к классу @TypeHeader ( developer = "Bob Bee" , lastModified = "2013-02-12" , teamMembers = { "Ann" , "Dan" , "Fran" }, meaningOfLife = 42 )               public class SetCustomAnnotation { // Содержимое класса находится здесь }    
// Это пример кода, который обрабатывает аннотацию import java.lang.annotation.Annotation ; import java.lang.reflect.AnnotatedElement ;  public class UseCustomAnnotation { public static void main ( String [] args ) { Class < SetCustomAnnotation > classObject = SetCustomAnnotation . class ; readAnnotation ( classObject ); }                 static void readAnnotation ( AnnotatedElement element ) { try { System.out.println ( " Значения элемента аннотации : \n" ) ; if ( element.isAnnotationPresent ( TypeHeader.class ) ) { // getAnnotation возвращает тип аннотации Annotation singleAnnotation = element.getAnnotation ( TypeHeader.class ) ; TypeHeader header = ( TypeHeader ) singleAnnotation ;                      System.out.println ( "Разработчик : " + header.developer ( ) ) ; System.out.println ( " Последнее изменение : " + header.lastModified ( ) ) ;      // teamMembers возвращены как String [] System.out.print ( " Члены команды: " ) ; for ( String member : header.teamMembers ( ) ) System.out.print ( member + " , " ) ; System.out.print ( " \ n " ) ;           System.out.println ( " Смысл жизни : " + header.valueOfLife ( ) ) ; } } catch ( Exception exception ) { exception.printStackTrace ( ) ; } } }          

Смотрите также

Ссылки

  1. ^ "Аннотации". Sun Microsystems . Архивировано из оригинала 2011-09-25 . Получено 2011-09-30 ..
  2. ^ Sun Microsystems (2005). Спецификация языка Java(TM) (3-е изд.). Prentice Hall . ISBN 0-321-24678-0..
  3. ^ Дэр Обасанджо (2007). "СРАВНЕНИЕ ЯЗЫКА ПРОГРАММИРОВАНИЯ C# КОМПАНИИ MICROSOFT С ЯЗЫКОМ ПРОГРАММИРОВАНИЯ JAVA КОМПАНИИ SUN MICROSYSTEMS: Аннотации метаданных". Дэр Обасанджо. Архивировано из оригинала 2012-09-19 . Получено 2012-09-20 .
  4. ^ Ковард, Дэнни (2006-11-02). "JSR 175: Средство метаданных для языка программирования JavaTM". Процесс сообщества Java . Получено 2008-03-05 .
  5. ^ "Предопределенные типы аннотаций". Oracle Corporation . Получено 2016-12-17 .
  6. ^ "Встроенные аннотации: Стандартные аннотации" . Получено 17.12.2016 .

Внешние ссылки