В начало!  
Сделай закладку этой страницы в Digg Сделай закладку этой страницы в Del.icoi.us Сделай закладку этой страницы в Slashdot Сделай закладку этой страницы в Technorati
arrow Технологии arrow Java SE arrow Возможности Java: Аннотации


feed image


Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285

Warning: Division by zero in /home/sunadmin/developers.sun.ru/docs/mambots/content/geshibot/geshi.class.php on line 2285
Возможности Java: Аннотации
Автор Надежда Саноцкая, Андрей Дмитриев   
01.11.2008 г.
Метаданные в коде программы на Java? Звучит загадочно, но на самом деле это вовсе не так сложно и зачастую очень полезно.

 

При разработке нередко возникают ситуации, когда необходимо создать  значительного количество стандартного кода. Естественно, писать однотипный код вручную - непродуктивно. Используя аннотации эту задачу можно упростить. Например, пометив удаленно доступные методы специальными аннотациями, можно возпользоваться инструментарием, который автоматически сгенерит JAX-RPC шаблон для этого кода, что значительно уменьшает объем рутинной работы при создании Веб-сервисов.

 

Другая частая ситуация - необходимость поддерживать внешние файлы, которые должны быть синхронизированы с кодом программы. Например, JavaBeans требует, чтобы класс BeanInfo был синхронизирован с самим bean, а Enterprise JavaBeans (EJB) подразумевает наличие корректного дескриптора. Проще и надежнее, если вместо обновления дополнительного внешнего файла, требуемая дополнительная информация хранилась бы прямо в коде в виде аннотаций.

 

В платформе Java уже давно есть специализированные аннотации. Например, модификатор transient - это аннотация, указывающая, что поле должно при выполнении сериализации, а тег javadoc @deprecated - аннотация, указывающая, что метод устарел и не рекомендован к использованию.

 

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

 

Аннотации непосредственно не затрагивают семантику программы, но они влияют на интерпретацию программы инструментами и библиотеками, а те, в свою очередь, могут затронуть семантику исполняемой программы. Информацию о существующих  аннотациях можно получить как из исходного кода, так и из откомпилированной программы (class файлов), а также во время исполнения программы, используя механизмы reflection.
 
Аннотации можно рассматривать, как расширение возможностей тегов javadoc. Если вам нужен механизм для изменения структуры или создания документации, то рекомендуется использовать тэги javadoc; иначе, используйте аннотации.

Разработчикам редко требуется определять собственные типы аннотаций, хоть это и не сложно. Описание типа аннотации похоже на описание обычного интерфейса, где ключевому слову interface предщедствует символ @. Описание метода - это определение элемента типа аннотации. При этом:
  • Запрещено использование параметров и конструкции throws.
  • Разрешены только несколько типов для возвращаемых значений: String, Class, enum, тип аннотации, массивом разрешенных типов.
  • Методы могут иметь значения по умолчанию. 
Вот пример описания типа аннотации:
  1. <font class="code" face="Courier">/**
  2. * Describes the Request-For-Enhancement(RFE) that led
  3. * to the presence of the annotated API element.
  4. */
  5. public @interface RequestForEnhancement {
  6. int id();
  7. String synopsis();
  8. String engineer() default "[unassigned]";
  9. String date(); default "[unimplemented]";
  10. }</font>
 
Определив новый тип аннотаций, Вы можете использовать его для аннотирования деклараций в вашем Java коде. Аннотация - это специальный вид модификатора, который может использоваться везде, где разрешены другие модификаторы (например, public, static или final). Аннотации принято указывать до других модификаторов. Аннотация состоит из символа @, типа аннотации и списка пар элемент-значение (список заключен в скобки). При этом значения должны быть статическими константами. Для примера, вот применение объявленного нами выше типа аннотаций:
  1. <font class="code" face="Courier">@RequestForEnhancement(
  2. id = 2868724,
  3. synopsis = "Enable time-travel",
  4. engineer = "Mr. Peabody",
  5. date = "4/1/3007"
  6. )
  7.  
  8. public static void travelThroughTime(Date destination) { ... }</font>
 

Можно определять "пустые" аннотации, т.е. аннотации без элементов. Такие типы аннотаций принято называть маркерными типами аннотаций (marker annotation type). Например:
  1. <font class="code" face="Courier">/**
  2. * Indicates that the specification of the annotated API element
  3. * is preliminary and subject to change.
  4. */
  5.  
  6. public @interface Preliminary { }</font><font face="Courier">
  7. </font>
 
Для маркерных аннотаций допустимо опускать круглые скобки при их использовании, например: 

  1. <font class="code" face="Courier">@Preliminary public class TimeTravel { ... }</font>
 
Для аннотаций с единственным элементом, элемент стоит называть value, как показано ниже:
  1. <font class="code" face="Courier">/**
  2. * Associates a copyright notice with the annotated API element.
  3. */
  4.  
  5. public @interface Copyright {
  6. String value();
  7. }</font>
 
Для таких аннотаций допустимо опускать название элемента и знак равенства (=) при их использовании:
  1. <font class="code" face="Courier">@Copyright("2002 Yoyodyne Propulsion Systems")
  2.  
  3. public class OscillationOverthruster { ... }</font>
 
Чтобы продемонстрировать как все это работает, мы покажем как можно использовать аннотации для создания простой  инфраструктуры для тестирования приложения.

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

  1. <font class="code" face="Courier">import java.lang.annotation.*;
  2.  
  3. /**
  4. * Указывает, что помеченный метод предназначен для тестирования.
  5. * Аннотацию можно использовать только со статическими методами без параметров.
  6. */
  7.  
  8. @Retention(RetentionPolicy.RUNTIME)
  9. @Target(ElementType.METHOD)
  10. public @interface Test { }</font><font face="Courier">
  11. </font>
 

Обратите внимание, что в этом примере описание типа аннотации само является аннотированным! Аннотации для аннотаций называются мета-аннотациями. Первая аннотация (@Retention(RetentionPolicy.RUNTIME)) указывает, что объявляемая аннотация должна сохраняться виртуальной машиной, чтобы ее было можно получить во время работы программы. Вторая аннотация (@Target(ElementType.METHOD)) указывает, что объявляемый тип аннотаций может использоваться только для аннотирования методов.

Ниже приведен пример программы, некоторые методы которой аннотированы нашей аннотацией @Test:
  1. <font class="code" face="Courier">public class Foo {
  2. @Test public static void m1() { }
  3. public static void m2() { }
  4. @Test public static void m3() {
  5. throw new RuntimeException("Boom");
  6. }
  7. public static void m4() { }
  8. @Test public static void m5() { }
  9. public static void m6() { }
  10. @Test public static void m7() {
  11. throw new RuntimeException("Crash");
  12. }
  13. public static void m8() { }
  14. }</font>
  15.  
  16.  
 

А вот так выглядит кол простого инструмента для исполнения тестов:

  1. <font class="code" face="Courier">import java.lang.reflect.*;
  2.  
  3. public class RunTests {
  4. public static void main(String[] args) throws Exception {
  5. int passed = 0, failed = 0;
  6. for (Method m : Class.forName(args[0]).getMethods()) {
  7. if (m.isAnnotationPresent(Test.class)) {
  8. try {
  9. m.invoke(null);
  10. passed++;
  11. } catch (Throwable ex) {
  12. System.out.printf("Test %s failed: %s %n", m, ex.getCause());
  13. failed++;
  14. }
  15. }
  16. }
  17. System.out.printf("Passed: %d, Failed %d%n", passed, failed);
  18. }
  19. }</font>
 

Инструмент тестирования получает имя класса для тестирования, как аргумент командной строки, перебирает все методы этого класса и запускает все методы, которые аннотированы аннотацией @Test. Предполагая, что провалившиеся тесты генерируют исключения, можно легко посчитать сколько тестов было выполнено успешно и сколько неудачно.

Вот пример результата работы этой программы для класса Foo (который мы определили выше):

  1. <font class="code" face="Courier">$ java RunTests Foo
  2.  
  3. Test public static void Foo.m3() failed: java.lang.RuntimeException: Boom
  4. Test public static void Foo.m7() failed: java.lang.RuntimeException: Crash
  5. Passed: 2, Failed 2</font>
 

И хотя, этот инструмент тестирования - поделка с большим числом ограничений, он демонстрирует возможности аннотаций и может быть легко расширен до практически полезного инструмента.

 Перевод Саноцкая Надежда, Дмитриев Андрей.

Оригинал 

 

Добавить комментарий


Защитный код
Обновить