| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <!-- |
| Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. |
| --> |
| <html> |
| <head> |
| <title>Поддержка обработчиков аннотаций в IDE NetBeans</title> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" > |
| <link rel="stylesheet" type="text/css" href="../../../netbeans.css"> |
| <meta name="keywords" content="NETBEANS, TUTORIAL, GUIDE, USER, DOCUMENTATION"> |
| <meta name="description" content="A very simple and quick introduction to the NetBeans IDE workflow by walking you through the creation of a |
| simple Hello World Java console application." > |
| </head> |
| |
| <body> |
| |
| <h1>Поддержка обработчиков аннотаций в IDE NetBeans (часть II) Использование пользовательских обработчиков аннотаций в IDE </h1> |
| <p><em>Составитель:, автор и редактор: Ирина Филиппова (Irina Filippova) </em></p> |
| <div class="margin-around"> |
| <div class="feedback-box margin-around float-left" style="margin-right:15px"> |
| <p><b>Содержание</b></p> |
| |
| <ul class="toc"> |
| <li><a href="annotations.html">Введение</a></li> |
| <li><a href="annotations.html#map">Отображение параметров javac и команд среды IDE</a> </li> |
| <li><a href="annotations-lombok.html">Использование проекта Lombok для пользовательских аннотаций</a></li> |
| <li><strong>Использование пользовательских обработчиков аннотаций в среде IDE</strong> |
| <ul> |
| <li><a href="#defineann">Определение аннотации и создание обработчика аннотаций</a></li> |
| <li><a href="#useprocessor">Использование обработчика аннотаций</a> </li> |
| </ul> |
| </li> |
| <li><a href="#seealso" title="Дополнительные сведения"><strong>Дополнительные сведения </strong></a></li> |
| </ul> |
| </div> |
| </div> |
| <img alt="Содержимое на этой странице применимо к IDE NetBeans 6.9, 7.0 и 7.1" class="stamp" src="../../../images_www/articles/71/netbeans-stamp-71-72-73.png" title="Содержимое этой страницы применимо к IDE NetBeans 6.9, 7.0 и 7.1" width="114" /> |
| <p>В этом разделе учебного курса описываются способы добавления собственного обработчика особых аннотаций в проект в среде IDE. Написание обработчика не входит в круг задач данного учебного курса. Здесь описывается добавление его к проекту IDE NetBeans. </p> |
| <p>Образец приложения, используемый в этом приложении, был создан Джесси Глик (Jesse Glick) и опубликован как <a href="http://wiki.netbeans.org/FaqApt" target="_blank">Часто задаваемые вопросы по вводу</a> для предыдущих выпусков IDE. </p> |
| <p>Обработчик аннотаций, используемый в качестве примера, создает родительский класс для аннотированного класса. Созданный родительский класс также содержит метод, вызываемый из аннотированного класса. Следуйте указаниям по созданию и добавлению обработчика особых аннотаций в проект среды IDE, приведенным ниже. </p> |
| <p style="clear:both"><b>Для работы с этим учебным курсом требуются программное обеспечение и ресурсы, перечисленные ниже.</b></p> |
| |
| <table> |
| <tbody> |
| <tr> |
| <th class="tblheader" scope="col">Программное обеспечение или материал</th> |
| <th class="tblheader" scope="col">Требуемая версия</th> |
| </tr> |
| <tr> |
| <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">IDE NetBeans</a></td> |
| <td class="tbltd1">7.1, 7.2, 7.3</td> |
| </tr> |
| <tr> |
| <td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Комплект для разработчика на языке Java (JDK)</a></td> |
| <td class="tbltd1">версия 6</td> |
| </tr> |
| |
| </tbody> |
| </table> |
| |
| <p><strong class="notes">Примечания:</strong></p> |
| <ul> |
| <li>В IDE NetBeans выпуске 6.9 была добавлена поддержка нестандартных обработчиков аннотаций. Этот учебный курс не подходит для использования с предыдущими версиями среды IDE. </li> |
| </ul> |
| |
| <h2><a name="defineann"></a>Определение аннотации и создание обработчика аннотаций</h2> |
| <p>В этом упражнении мы создадим проект библиотеки классов.</p> |
| <ol> |
| <li>Выберите File ("Файл") > New Project ("Создать проект") и выберите тип проекта Java Class Library ("Библиотека классов Java") в категории Java. Нажмите кнопку "Далее".</li> |
| <li>Введите <tt>AnnProcessor</tt> в поле Project Name ("Имя проекта") и укажите местоположение для проекта. Нажмите кнопку "Завершить". |
| <p>При нажатии кнопки "Готово" среда IDE создаст проект библиотеки классов, который появится в окне Projects ("Проекты").</p> |
| </li> |
| <li>Щелкните правой кнопкой мыши узел проекта AnnProcessor в окне Projects ("Проекты") и выберите Properties ("Свойства").</li> |
| <li>В категории Sources ("Источники") подтвердите, что для JDK 6 указан формат исходного кода/двоичный.</li> |
| <li>Выберите вкладку Libraries ("Библиотеки") и подтвердите, что платформой Java является JDK 6. Нажмите кнопку "ОК", чтобы закрыть окно Project Properties ("Свойства проекта").</li> |
| </ol> |
| |
| <p>В этом упражнении мы создадим несколько пакетов Java и по одному классу Java в каждом из пакетов.</p> |
| <ol> |
| <li>Создайте пакет Java с именем <strong><tt>ann</tt></strong> щелкнув правой кнопкой мыши узел 'Исходные пакеты' в проекте AnnProcessor и выбрав 'Создать' > 'Пакет Java'. Введите <tt>ann</tt> в поле Package Name ("Имя пакета") и нажмите кнопку Finish ("Готово").</li> |
| <li>Повторите предыдущее действие и создайте пакет Java под названием <strong><tt>proc</tt></strong>. |
| <p>После создания двух пакетов Java структура проекта должна быть подобной изображенной ниже.</p> |
| <img alt="снимок окна 'Проекты', в котором отображаются пакеты Java" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/packages.png" title="Структура проекта для обработчика аннотаций."></li> |
| <li>Щелкните правой кнопкой мыши пакет Java <tt>ann</tt> и выберите New ("Создать") > Java class ("Класс Java").</li> |
| <li>Введите <strong><tt>Handleable</tt></strong> в поле Class Name ("Имя класса"). Нажмите кнопку "Завершить".</li> |
| <li>Измените файл <tt>Handleable.java</tt>, добавив приведенный ниже код. Сохраните файл. |
| <pre>package ann; |
| |
| public <strong>@interface</strong> Handleable { |
| |
| }</pre> |
| |
| <p>Так объявляются аннотации -- совершенно аналогично объявлению интерфейса. Различием является то, что ключевому слову <tt>interface</tt> должен предшествовать знак <tt>@</tt>. Эта аннотация именуется <tt>Handleable</tt> (обрабатываемой).</p> |
| |
| <p class="notes"><strong>Дополнительные сведения.</strong> В объявлениях аннотаций можно указать дополнительные параметры, например, типы элементов, к которым можно добавить аннотации, например, классы или методы. Для этого добавляется <tt>@Target(value = {ElementType.TYPE})</tt> для классов и <tt>@Target(value = {ElementType.METHOD}).</tt> Таким образом, объявление аннотаций становится автоматическим с помощью <em>мета-аннотаций</em>. </p> |
| |
| <p>Теперь необходимо добавить к обработчику аннотаций код для обработки аннотации <tt>Handleable</tt>.<p> |
| </li> |
| <li>Щелкните правой кнопкой мыши пакет<strong><tt> Java </tt>proc</strong> и выберите New ("Создать") > Java class ("Класс Java").</li> |
| <li>Введите <strong><tt>HandleableProcessor</tt></strong> в поле Class Name ("Имя класса"). Нажмите кнопку "Завершить".</li> |
| <li>Измените класс <tt>HandleableProcessor.java</tt>, добавив нижеприведенный код. Сохраните изменения. |
| <pre class="examplecode">package proc; |
| |
| import ann.Handleable; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.io.Writer; |
| import java.util.Set; |
| import javax.annotation.processing.AbstractProcessor; |
| import javax.annotation.processing.RoundEnvironment; |
| import javax.annotation.processing.SupportedAnnotationTypes; |
| import javax.annotation.processing.SupportedSourceVersion; |
| import javax.lang.model.SourceVersion; |
| import javax.lang.model.element.Element; |
| import javax.lang.model.element.ElementKind; |
| import javax.lang.model.element.TypeElement; |
| import javax.lang.model.type.TypeMirror; |
| import javax.tools.Diagnostic; |
| import javax.tools.JavaFileObject; |
| |
| @SupportedAnnotationTypes("ann.Handleable") |
| @SupportedSourceVersion(SourceVersion.RELEASE_6) |
| public class HandleableProcessor extends AbstractProcessor { |
| |
| /** public for ServiceLoader */ |
| public HandleableProcessor() { |
| } |
| |
| public boolean process(Set annotations, |
| RoundEnvironment roundEnv) { |
| for (Element e : roundEnv.getElementsAnnotatedWith(Handleable.class)) { |
| if (e.getKind() != ElementKind.FIELD) { |
| processingEnv.getMessager().printMessage( |
| Diagnostic.Kind.WARNING, |
| "Not a field", e); |
| continue; |
| } |
| String name = capitalize(e.getSimpleName().toString()); |
| TypeElement clazz = (TypeElement) e.getEnclosingElement(); |
| try { |
| JavaFileObject f = processingEnv.getFiler(). |
| createSourceFile(clazz.getQualifiedName() + "Extras"); |
| processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, |
| "Creating " + f.toUri()); |
| Writer w = f.openWriter(); |
| try { |
| PrintWriter pw = new PrintWriter(w); |
| pw.println("package " |
| + clazz.getEnclosingElement().getSimpleName() + ";"); |
| pw.println("public abstract class " |
| + clazz.getSimpleName() + "Extras {"); |
| pw.println(" protected " + clazz.getSimpleName() |
| + "Extras() {}"); |
| TypeMirror type = e.asType(); |
| pw.println(" /** Handle something. */"); |
| pw.println(" protected final void handle" + name |
| + "(" + type + " value) {"); |
| pw.println(" System.out.println(value);"); |
| pw.println(" }"); |
| pw.println("}"); |
| pw.flush(); |
| } finally { |
| w.close(); |
| } |
| } catch (IOException x) { |
| processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, |
| x.toString()); |
| } |
| } |
| return true; |
| } |
| |
| private static String capitalize(String name) { |
| char[] c = name.toCharArray(); |
| c[0] = Character.toUpperCase(c[0]); |
| return new String(c); |
| } |
| }</pre> |
| <p>Давайте рассмотрим внимательнее основные части кода, образующие обработчик аннотаций (обратите внимание, что для удобства рассмотрения код приведен здесь лишь частично). </p> |
| <p>Сперва следует указать типы аннотаций, поддерживаемые обработчиком аннотаций (используя <tt>@SupportedAnnotationTypes</tt>) и поддерживаемую версию исходных файлов (используя <tt>@SupportedSourceVersion</tt>). В данном случае версией является JDK 6: <br> |
| <pre class="examplecode"> |
| @SupportedAnnotationTypes("ann.Handleable") |
| @SupportedSourceVersion(SourceVersion.RELEASE_6)</pre> |
| <p>Затем следует объявить общедоступный класс для обработчика, расширяющий класс<tt>AbstractProcessor</tt> из пакета <tt>javax.annotation.processing</tt>. <tt>AbstractProcessor</tt> является стандартным надклассом для обработчиков конкретных аннотаций и содержит необходимые методы для обработки аннотаций.</p> |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor { |
| ... |
| }</pre> |
| <p>Теперь необходимо предоставить общедоступный конструктор для данного класса.</p> |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor { |
| <strong> public HandleableProcessor() { |
| }</strong> |
| ... |
| |
| }</pre> |
| <p>Затем следует вызвать метод <tt>process</tt>() родительского класса <tt>AbstractProcessor</tt>. Посредством этого метода предоставляются аннотации, доступные для обработки. Кроме того, этот метод содержит данные о цикле обработки.</p> |
| |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor {<strong> |
| </strong>... |
| <strong> public boolean process(Set annotations, |
| RoundEnvironment roundEnv) { |
| ... |
| } |
| </strong> |
| }</pre> |
| <p>Логика обработчика аннотаций содержится внутри метода <tt>process()</tt> класса <tt>AbstractProcessor</tt>. Обратите внимание, что при помощи класса <tt>AbstractProcessor</tt> также можно получить доступ к интерфейсу <tt>ProcessingEnvironment</tt>, позволяющему обработчикам аннотаций использовать несколько полезных функций, например средство для работы с файловой системой (обработчик файловой системы, позволяющий обработчикам аннотаций создавать файлы) и средство вывода сообщений (способ предупреждения об ошибках обработчиков аннотаций).</p> |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor {<strong> |
| </strong>... |
| public boolean process(Set annotations, |
| RoundEnvironment roundEnv) {<br> |
| //For each element annotated with the Handleable annotation |
| <strong>for (Element e : roundEnv.getElementsAnnotatedWith(Handleable.class)) { |
| <br> </strong>//Check if the type of the annotated element is not a field. If yes, return a warning<strong>.<br> if (e.getKind() != ElementKind.FIELD) {<br> processingEnv.getMessager().printMessage(<br> Diagnostic.Kind.WARNING,<br> "Not a field", e);<br> continue;<br> } |
| </strong>//Define the following variables: name and clazz<strong>.</strong><strong><br> String name = capitalize(e.getSimpleName().toString());<br> TypeElement clazz = (TypeElement) e.getEnclosingElement();<br> </strong>//Generate a source file with a specified class name. <strong> |
| try {<br> JavaFileObject f = processingEnv.getFiler().<br> createSourceFile(clazz.getQualifiedName() + "Extras");<br> processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,<br> "Creating " + f.toUri());<br> Writer w = f.openWriter();<br> </strong>//Add the content to the newly generated file<strong>. |
| try {<br> PrintWriter pw = new PrintWriter(w);<br> pw.println("package "<br> + clazz.getEnclosingElement().getSimpleName() + ";");<br> pw.println("public abstract class "<br> + clazz.getSimpleName() + "Extras {");<br> pw.println(" protected " + clazz.getSimpleName()<br> + "Extras() {}");<br> TypeMirror type = e.asType();<br> pw.println(" /** Handle something. */");<br> pw.println(" protected final void handle" + name<br> + "(" + type + " value) {");<br> pw.println(" System.out.println(value);");<br> pw.println(" }");<br> pw.println("}");<br> pw.flush();<br> } finally {<br> w.close();<br> }<br> } catch (IOException x) {<br> processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,<br> x.toString());<br> }<br> }</strong><br> return true; |
| <strong> }</strong> |
| ... |
| }</pre> |
| <p>В последнем блоке этого кода объявляется метод <tt>capitalize</tt>, используемый для написания имени аннотированного элемента с заглавной буквы.</p> |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor {<strong> |
| </strong>...<strong> |
| |
| private static String capitalize(String name) {<br> char[] c = name.toCharArray();<br> c[0] = Character.toUpperCase(c[0]);<br> return new String(c);<br> } |
| </strong>}</pre> |
| </li> |
| <li>Создайте проект, щелкнув правой кнопкой мыши проект <tt>AnnProcessor</tt> и выбрав 'Сборка'.</li> |
| </ol> |
| |
| |
| <h2><a name="useprocessor"></a>Работа с обработчиком аннотаций в среде IDE</h2> |
| <p>В этом разделе мы создадим приложение Java, в котором будет использоваться обработчик аннотаций.</p> |
| <ol> |
| <li>Выберите File ("Файл") > New Project ("Создать проект") и выберите тип проекта Java Application ("Приложение Java") в категории Java. Нажмите кнопку "Далее".</li> |
| <li>На странице Name and Location ("Имя и местоположение") введите <tt>Demo</tt> в поле Project Name ("Имя проекта") и укажите местоположение проекта.</li> |
| <li>Введите <strong><tt>demo.Main</tt></strong> в поле Create Main Class ("Создать главный класс"). Нажмите кнопку "Завершить".<br> <img alt="моментальный снимок мастера создания проектов" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-project-wizard.png" title="Создание проекта Demo в мастере создания проектов."></li> |
| |
| <li>Откройте окно свойств проекта и убедитесь, что JDK 6 выбран как двоичный формат/формат исходного кода на панели Sources ("Исходные коды"), а также что JDK 6 установлен как платформа Java на панели Libraries ("Библиотеки").</li> |
| <li>Измените класс <tt>Main.java</tt>, добавив приведенный ниже код. Сохраните изменения. |
| <pre class="examplecode">package demo; |
| |
| <strong>import ann.Handleable;</strong> |
| |
| public class Main <strong>extends MainExtras</strong> { |
| |
| <strong>@Handleable |
| private String stuff;</strong> |
| |
| <strong>public static void main(String[] args) { |
| new Main().handleStuff("hello"); |
| }</strong> |
| }</pre> |
| <p>Данный код содержит следующие элементы:</p> |
| <ul> |
| <li>оператор импорта для обработчика особых аннотаций <tt>ann.Handleable</tt>;</li> |
| <li>общедоступный класс <tt>Main</tt>, расширяющий класс <tt>MainExtras</tt> (<tt>MainExtras</tt> должен быть создан обработчиком аннотаций во время компиляции);</li> |
| <li>закрытое поле под названием <tt>stuff</tt>, с аннотацией <tt>@Handleable</tt>; </li> |
| <li>метод <tt>main</tt>, вызывающий метод <tt>handleStuff</tt>, который объявляется в автоматически создаваемом классе <tt>MainExtras</tt>. |
| |
| <p>В этом простом примере метод <tt>handleStuff</tt> только распечатывает текущее значение. Назначение метода можно изменить.</p></li> |
| </ul> |
| <p>После сохранения кода <tt>Main.java</tt> можно увидеть, что среда IDE сообщает о ряде ошибок компиляции. Это происходит, поскольку обработчик аннотаций еще не добавлен в проект.</p> |
| </li> |
| <li>Щелкните правой кнопкой мыши узел проекта <tt>Demo</tt> в окне Projects ("Проекты"), выберите Properties ("Свойства"), затем выберите категорию Libraries ("Библиотеки") в окне свойств.</li> |
| <li>На вкладке Compile ("Компиляция") щелкните Add Project ("Добавить проект") и найдите проект <tt>AnnProcessor</tt>.<br> <img alt="снимок вкладки 'Компилировать' в категории 'Библиотеки' окна свойств проекта" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-properties-compile.png" title="Вкладка 'Компилировать' в категории 'Библиотеки' окна свойств проекта"> |
| |
| <p>Вкладка "Компиляция" соответствует параметру <tt>-classpath</tt> <a href="http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#options" target="_blank">компилятора Java</a>. Поскольку обработчик аннотаций является единым файлом JAR, который содержит как определение аннотаций, так и обработчик аннотаций, его следует добавить к пути классов для проекта, которым является вкладка Compile ("Компиляция"). </p> |
| </li> |
| <li>Выберите категорию Compiling ("Компиляция") в окне Properties ("Свойства") и установите флажки Enable Annotation Processing ("Включить обработку аннотаций") и Enable Annotation Processing in Editor ("Включить обработку аннотаций в редакторе").</li> |
| <li>Укажите, какой обработчик аннотаций должен быть запущен, нажав кнопку Add ("Добавить") рядом с текстовой областью обработчиков аннотаций и введя <tt>proc.HandleableProcessor</tt> в поле FQN ("Полностью определенное имя") обработчика аннотаций. <br> <img alt="снимок диалогового окна 'FQN обработчика аннотаций'" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-processor-fqn.png" title="Диалоговое окно 'FQN обработчика аннотаций'"> |
| |
| <p>Категория Compiling ("Компиляция") в окне Properties ("Свойства") должна выглядеть, как на приведенном ниже изображении.</p> |
| <img alt="снимок категории "Компиляция" в окне "Свойства проекта"." class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-properties-compiling.png" title="Категория "Компиляция" в окне "Свойства проекта"."> |
| |
| </li> |
| <li>Нажмите кнопку OK в окне Properties ("Свойства"). |
| |
| <p class="notes"><strong>Примечание.</strong> В файле <tt>Main.java</tt> все еще могут отображаться ошибки компиляции. Это происходит, поскольку в среде IDE еще не определено местоположение файла <tt>MainExtras.java</tt>, в котором объявляется метод <tt>handleStuff</tt>. После первого создания проекта Demo будет создан файл <tt>MainExtras.java</tt>. Если для проекта включено режим Compile On Save ("Компилировать при сохранении"), среда IDE компилирует проект при сохранении <tt>Main.java</tt>.</p> |
| </li> |
| <li>Щелкните правой кнопкой мыши проект Demo и выберите Build ("Сборка"). |
| <p>Если после сборки проекта взглянуть на него в окне Projects ("Проекты"), то можно будет увидеть новый узел <tt>Generated Sources</tt> с файлом <tt>demo/MainExtras.java</tt>.</p> |
| <img alt="снимок окна 'Проекты' с созданными источниками" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-generated-sources.png" title="В окне 'Проекты' отображаются созданные источники"> |
| |
| <p>При просмотре содержимого созданного файла <tt>MainExtras.java</tt> можно увидеть, что обработчик аннотаций создал класс <tt>MainExtras</tt> с методом <tt>handleStuff</tt>. Метод <tt>handleStuff</tt> и является методом, вызываемым из аннотированного файла <tt>Main.java</tt>. </p> |
| <pre class="examplecode">package demo; |
| public abstract class MainExtras { |
| protected MainExtras() {} |
| /** Handle something. */ |
| protected final void handleStuff(java.lang.String value) { |
| System.out.println(value); |
| } |
| }</pre> |
| </li> |
| <li>Щелкните правой кнопкой мыши проект Demo и выберите Run ("Запустить"). |
| <p>При щелчке Run ("Запустить") в окне вывода можно будет увидеть следующее. Выполняется компиляция проекта Demo, и на экран выводится сообщение.</p> |
| <img alt="снимок окна 'Проекты' с созданными источниками" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-run.png" title="В окне 'Проекты' отображаются созданные источники"> |
| <!-- <img src="../../../images_www/articles/69/java/annotations/output-demo.png" alt="Output of the Demo project." width="408" height="123" class="margin-around"></li>--> |
| </ol> |
| <div class="feedback-box"><a href="/about/contact_form.html?to=3&subject=Feedback:%20Using%20the%20Annotation%20Processors%20Support%20in%20NetBeans%20IDE">Мы ждем ваших отзывов</a><br style="clear:both;" /> |
| </div> |
| <h2><a id="seealso" name="seealso"></a>Дополнительные сведения</h2> |
| <p>Ознакомьтесь со следующими ресурсами для получения дополнительных сведений об аннотациях в приложениях Java:</p> |
| <ul> |
| <li>Документация Java SE - <a href="http://download.oracle.com/javase/6/docs/technotes/guides/language/annotations.html" target="_blank">Аннотации</a></li> |
| <li>Учебный курс Java SE - <a href="http://download.oracle.com/javase/tutorial/java/javaOO/annotations.html" target="_blank">Аннотации</a> </li> |
| <li><a href="http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#processing" target="_blank">Компилятор Java: параметры обработки аннотаций</a> </li> |
| <li><a href="http://blogs.sun.com/darcy/">Блог Джозефа Д. Дарси (Joseph D. Darcy)</a> - полезные рекомендации от ведущего специалиста по спецификации JSR-269 </li> |
| </ul> |
| </body> |
| </html> |