Главная > Java Standard Edition > Введение в аннотации

Тема Зацепин
268

Java-разработчик 🧩
346
1 минуту

Введение в аннотации

J2SE содержит множество нововведений в самом языке Java, в том числе поддержка параметризуемых классов (generics) и улучшенного цикла for (enhanced for loop). В предыдущих статьях мы подробно рассказывали о параметризуемых классах и об улученном цикле for, а в этой статье мы рассмотрим аннотации, встроенные в J2SE 5.0.

Добавлено : 8 Mar 2009, 07:53

Что же такое аннотации? Аннотации - они же JSR-175 (Meta-data) - позволяют связывать метаданные с программными элементами (такими как классы, интерфейсы и методы). Они могут служить дополнительными модификаторами без изменения основного кода для своих элементов.

Само введение метаданных в исходный код не является новым для J2SE 5.0. Вы можете добавить тег @deprecated в комментариях к методу в javadoc, и компилятор будет обрабатывать его как метаданные метода. Такая возможность появилась с выходом версии J2SE 1.0. Уже начальный релиз платформы был ориентирован на сокращение использования метода getenv() (хотя это было реализовано только в версии 1.1). Суть осталась той же, за исключением символа @ в синтаксисе. Изменилось только место -- тег аннотации перешел в код, а не в комментарий. Преимущество в том, что аннотации являются способом поддержки программной модели объявлений.

Итак, первая аннотация, которая идет с J2SE 5.0: @Deprecated. Обратите внимание, что здесь заглавная буква D. @Deprecated функционально работает в коде также как и @deprecated в javadoc, связанный с классом или методом. С помощью флагов и тега @Deprecated вы сообщаете компьютеру предупредить пользователя, что используется тот или иной класс или метод.

Класс Main содержит метод deprecatedMethod(), у которого флагом является аннотация @Deprecated, а комментарием @deprecated:

public class Main {

/**
*
@deprecated устарел. Используйте вместо него Use System.foobar().
*/

@Deprecated
public static void deprecatedMethod() {
System.out.println("Don't call me");
}
}

Компилируйте класс с аннотацией так же, как без нее:

> javac Main.java

Как и следовало ожидать, получился класс Main.class.

Если вы используете метод deprecated, то получите предупреждение при компиляции - такое же, как при использовании тега @deprecated в javadoc. Пример:

public class User {
public static void main(String args[]) {
Main.deprecatedMethod();
}
}

Скомпилируется:

> javac User.java

и вы увидите следующее предупреждение об использовании класса deprecated:

Note: User.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation
for details.

User.java использует или заменяет deprecated API. Перекомпилируйте с -Xlint:deprecation, чтобы посмотреть детали. Добавление -Xlint в строку компиляции покажет, что именно не так:

> javac -Xlint:deprecation User.java

User.java:
3: warning: [deprecation] deprecatedMethod() in
Main has been deprecated
Main.deprecatedMethod
();
^
1 warning

Замена комментария @deprecated на аннотацию @Deprecated не принесет ничего существенно нового в систему. Это слега изменяет способ, но делает все то же самое. А вот следующие две аннотации @Override и @SuppressWarnings действительно меняют функциональность платформы.

Аннотация @Override может использоваться вместе с объявлением метода. После того как вы ввели имя, можете добавить аннотацию @Override для установки значение флага функции, чтобы переписать метод суперкласса. Зачем так делать? Чтобы найти ошибку раньше. Сколько раз вы собирались переписать метод, но то в названии метода была ошибка, то определены неправильные аргументы, а то неверный тип возвращаемого значения? Иными словами, сколько раз вам приходилось создавать новый метод вместо того, чтобы переписать уже существующий? Используя @Override, вы найдете ошибку в текущем классе намного раньше:

public class Overrode {
@Override
public int hashcode() {
return 0;
}

@Override
public boolean equals(Object o) {
return true;
}
}

Здесь ошибка в том, что название метода должно быть hashCode, а не hashcode. Предполагается, что объявление метода находится где-то в описании класса. Если не использовать первую аннотацию @Override, сколько у вас займет времени, чтобы обнаружить, что ваш метод hashCode (с заглваной буквой) не вызывается, и вы получаете некоторый результат по умолчанию от родительского класса Object. Благодаря аннотации @Override, компиляция класса выдаст ошибку, сообщающую вам о проблеме (метод не переписывается из своего суперкласса):

> javac Overrode.java

Overrode.java:
2: method does not override a method from its
superclass
@Override
^
1 error

Чем скорее вы найдете ошибку такого происхождения, время на ее исправление сильно сокращается. Обратите внимание, что метод hashCode никогда не возвращает константу. Более подробное описание использования hashCode и equals() вы найдете в 8 пункте в книге Джошуа Блош "Путеводитель по эффективному программированию на Java".

Последняя из трех новых аннотаций в J2SE 5.0 - @SuppressWarnings - самая интересная. Она сообщает компилятору не предупреждать вас, о чем он обычно предупреждает. Предупреждения относятся к разным категориям, и вы можете сообщить аннотации, какие категории вас интересуют. Компилятор javac определяет семь свойств для вывода предупреждений: все, deprecation, непроверенные, проход при невыполнении условия, неверные пути, последовательные и конечные. (В спецификации языка определены только два из этих типов: deprecation и непроверенные.)

В целях демонстрации, посмотрим на блокировку опции "проход при невыполненных условиях". Начнем со следующего класса. В этом классе пропущено break в каждом случае switch:

public class Fall {
public static void main(String args[]) {
int i = args.length;
switch (i) {
case 0:
System.out.println
("0");
case 1:
System.out.println
("1");
case 2:
System.out.println
("2");
case 3:
System.out.println
("3");
default:
System.out.println
("Default");

}
}
}

Скомпилируйте класс с помощью javac. Вы увидите, что просто создается файл .class без всяких предупреждений:

javac Fall.java

Если вы хотите, чтобы компилятор предупреждал вас о невыполнении условий switch (т.е. что пропущено одно или более утверждений break), скомпилируйте с опцией Xlint:fallthrough :

javac -Xlint:fallthrough Fall.java

Вы увидите следующие предупреждения:

Fall.java:6: warning: [fallthrough] possible fall-through into case case 1: System.out.println("1"); ^ Fall.java:7: warning: [fallthrough] possible fall-through into case case 2: System.out.println("2"); ^ Fall.java:8: warning: [fallthrough] possible fall-through into case case 3: System.out.println("3"); ^ Fall.java:9: warning: [fallthrough] possible fall-through into case default : System.out.println("Default"); ^ 4 warnings

Что делать, если вы не придаете значения тому, что в каждом случае switch пропускается break? Вот где вам пригодится аннотация @SuppressWarnings. Вставьте эту строчку перед объявлением метода main():

@SuppressWarnings("fallthrough")

Скомпилируйте с опцией -Xlint:fallthrough:

javac -Xlint:fallthrough Fall.java

и получите файл .class без единого предупреждения.

Аннотация @SuppressWarnings может использоваться для подавления других предупреждений, например, когда вы используете коллекции, не указывая типа данных элементов коллекции. Не стоит использовать аннотацию @SuppressWarnings, чтобы просто избежать предупреждений компилятора. Применяйте это там, где нельзя избежать предупреждений, например, при использовании библиотеки, которая не была создана вместе с параметризуемыми классами (generics).

Это что касается встраиваемых аннотаций. Маленькое дополнение: аннотации (со своими аргументами) обычно определяются отдельной строкой сами по себе.

Определяя свои собственные аннотации, вы можете сделать намного больше, чем просто использовать аннотации, введенные в J2SE 5.0. Здесь вы узнаете, как создавать свои аннотации.

Теги: annotationsjava 5

Еще от автора

Применение WeakHashmap для списков слушателей

В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.

Заставки в Mustang

Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.

Совмещение изображений

1 Введение 2 Правила визуализации и пример 3 Совмещение изображений в оперативной памяти 4 Постепенное исчезновение изображения 5 Ссылки и дополнительная информация

Еще по теме

Применение WeakHashmap для списков слушателей

В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.

Заставки в Mustang

Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.

Использование потоков

1 Введение 2 Работа с выражениями типа Boolean 3 Класс JoptionPane 4 Приложение-счетчик 5 Ссылки

Перехват необрабатываемых исключений

В статье от 16 марта 2004 года Best Practices in Exception Handling были описаны приемы обработки исключений. В данной статье вы изучите новый способ обработки исключений при помощи класса UncaughtExceptionHandler добавленного в J2SE 5.0.

Использование класса LinkedHashMap

1 Введение 2 Сортировка хэш-таблицы 3 Копирование таблицы 4 Сохранение порядка доступа к элементам 5 Ссылки

Сказ про кодировки и java

С кодировками в java плохо. Т.е., наоборот, все идеально хорошо: внутреннее представление строк – Utf16-BE (и поддержка Unicode была с самых первых дней). Все возможные функции умеют преобразовывать строку из маленького регистра в большой, проверять является ли данный символ буквой или цифрой, выполнять поиск в строке (в том числе с регулярными выражениями) и прочее и прочее. Для этих операций не нужно использовать какие-то посторонние библиотеки вроде привычных для php mbstring или iconv. Как говорится, поддержка многоязычных тестов “есть в коробке”. Так откуда берутся проблемы? Проблемы возникают, как только строки текста пытаются “выбраться” из jvm (операции вывода текста различным потребителям) или наоборот пытаются в эту самую jvm “залезть” (операция чтения данных от некоторого поставщика).