stringtranslate.com

Java-аннотация

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

История

Платформа Java имеет различные механизмы специальных аннотаций, например transientмодификатор или @Deprecatedтег javadoc. Запрос на спецификацию Java JSR-175 представил возможность аннотаций общего назначения (также известных как метаданные ) в процессе сообщества Java в 2002 году; он получил одобрение в сентябре 2004 года. [4] Аннотации стали доступны в самом языке, начиная с версии 1.5 Java Development Kit (JDK). Инструмент предоставил временный интерфейс для обработки аннотаций во время компиляции в JDK версии 1.5 apt; JSR-269 формализовал это, и в версии 1.6 он был интегрирован в компилятор javac .

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

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

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

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

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

Пример

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

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

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

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

Объявления типов аннотаций аналогичны обычным объявлениям интерфейсов. Знак (@) предшествует ключевому слову «интерфейс».

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

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

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

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

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

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

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

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

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

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

пакет com.annotation ; импортировать java.lang.annotation.Documented ; импортировать java.lang.annotation.ElementType ; импортировать java.lang.annotation.Inherited ; импортировать java.lang.annotation.Retention ; импортировать java.lang.annotation.RetentionPolicy ; импортировать 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 Unfinished { public enum Priority { LOW , MEDIUM , HIGH } Строковое значение (); Строка [] изменена по () по умолчанию "" ; String [] lastChangedBy () default "" ; Приоритет Priority () Приоритет по умолчанию . СЕРЕДИНА ; Строка CreatedBy () по умолчанию "Джеймс Гослинг" ; Строка LastChanged () по умолчанию «2011-07-08» ; }                                 
пакет com.annotation ; public @interface UnderConstruction { String Owner () default "Патрик Нотон" ; Строковое значение () по умолчанию «Объект находится в стадии строительства». ; Строка создано () по умолчанию "Майк Шеридан" ; Строка LastChanged () по умолчанию «2011-07-08» ; }                   
пакет com.validators ; импортировать javax.faces.application.FacesMessage ; импортировать javax.faces.comComponent.UIComponent ; импортировать javax.faces.context.FacesContext ; импортировать javax.faces.validator.Validator ; импортировать javax.faces.validator.ValidatorException ;     импортировать com.annotation.UnderConstruction ; импортировать com.annotation.Unfinished ; импортировать com.annotation.Unfinished.Priority ; импортировать com.util.Util ;    @UnderConstruction ( владелец = «Джон Доу» ) общедоступный класс DateValidator реализует Validator { public void validate ( контекст FacesContext , компонент UIComponent , значение объекта ) выдает ValidatorException { String date = ( String ) value ; String errorLabel = «Пожалуйста, введите правильную дату». ; если ( ! компонент . getAttributes (). isEmpty ()) { errorLabel = ( String ) компонент . Получить Атрибуты (). получить ( "ошибкадисплейвал" ); }                                  if ( ! Util . validateAGivenDate ( date )) { @Unfinished ( changedBy = "Steve" , value = "добавлять сообщение в контекст или нет, подтвердите" , Priority = Priority . HIGH ) FacesMessage message = new FacesMessage (); сообщение . setSeverity ( FacesMessage . SEVERITY_ERROR ); сообщение . setSummary ( errorLabel ); сообщение . setDetail ( метка ошибки ); выдать новое исключение ValidatorException ( сообщение ); } } }                         

Обработка

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

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

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

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

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

Рекомендации

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

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