Если вы когда-либо видели кодовую базу Java, есть большая вероятность, что вы видели и что-то вроде @Override
или подобного перед методом или классом. Такие тэги называются аннотациями. Аннотации — это тэги метаданных, которые помогают определить дополнительную информацию для классов, интерфейсов, методов или полей. Аннотации не добавляют дополнительной реализации к функциональному коду, но помогают с необязательной информацией, такой как:
- Информация для компилятора. Компилятор может использовать аннотации для обнаружения ошибок или подавления предупреждений.
- Информация для разработчика. Когда кто-то просматривает код, аннотации помогают сделать его читабельным и более легким для понимания.
- Обработка времени компиляции и развертывания. Программные средства могут обрабатывать аннотации для создания кода, XML-файлов и т.д.
- Обработка во время выполнения. Аннотации могут проверяться во время выполнения для прохождения тестов.
Java содержит целый набор предопределенных аннотаций и даже позволяет определять свои собственные. Ниже приведем список наиболее широко распространенных и важных аннотаций.
Предопределенные аннотации
@Override
Аннотация @Override
сообщает компилятору, что элемент подкласса переопределяет элемент родительского класса или суперкласса. Хотя эта аннотация не обязательна при переопределении метода, она помогает предотвратить ошибки. Если метод, помеченный как “override”, не может правильно переопределить метод суперкласса, компилятор выдает ошибку.
class Avatar {
public void destroyEvil() { ... } // переопределенный
}
class Aang extends Avatar {
@Override
// overriding method
public void destroyEvil() { ... }
}
@SuppressWarnings
Предупреждения компилятора полезны, если вы их читаете, но они часто создают “шум” в терминале. @SuppressWarnings
будет подавлять эти предупреждения. Компилятор Java может выдавать множество предупреждений, но с помощью @SuppressWarnings
вы можете скрыть все предупреждения или выбрать предупреждения, появления которых вам хочется избежать.
@SuppressWarnings({“unchecked”, “deprecated”})
будет скрывать предупреждения о непроверенных (unchecked) и устаревших (deprecated) методах.
@SuppressWarnings("unchecked")
void uncheckedWarning() {
List words = new ArrayList();
words.add("hello"); //выбрасывает предупреждение о непроверенном
}
@deprecated
Обозначение @deprecated
также очень распространено. Это означает, что аннотированный метод устарел и больше не поддерживается разработчиками. Компилятор не будет обрабатывать устаревший метод иначе, чем обычный метод. Таким образом, даже если метод допустимо вызвать, возвращаемый им ответ может быть не идеальным. Это документация для разработчиков.
@depricated
public String prepareForY2K() { ... }
@author
Тэг @author
— простая аннотация, документирующая автора метода или файла. Обычно соединяется с некоторой дополнительной информацией, такой как версия, номер релиза и т.д.
Oracle рекомендует писать тэги в следующем порядке:
@author
— документирует автора кода;@version
— обеспечивает только одно обновление за раз (позволяет избежать блокировки);@param
— документирует имя и описание параметров;@return
— документирует возвращаемое значение; опускать, если возвращает пустоту (void);@throws
— документирует проверенные исключения (объявленные вthrows
);@see
— ссылка или указание на ссылку;@since
— документирует версию продукта, с которой была добавлена новая функциональность;@deprecated
— документирует, что код больше не поддерживается.
Тест-аннотации
Написание тестов — важнейший аспект цикла разработки и так же (если не более) важно, как и написание самой кодовой базы. Существуют различные аннотации, созданные явно для тестов.
@Test
@Test
сообщает JUnit, что аннотированный метод должен выполняться как тест. Чтобы запустить метод, JUnit создает новый экземпляр класса, а затем вызывает тестовый метод.
Для этой аннотации можно указать два необязательных параметра:
@Timeout
приводит к сбою метода тестирования, если выполнение занимает больше времени, чем указанное время, измеренное на часах в миллисекундах.
Например, следующий тест упадет (через 0,1 секунды):
@Test(timeout=100)
public void toInfinityAndBeyond() {
while(true);
}
@Expected
объявляет, что тестовый метод должен выдавать определенное исключение, в противном случае тест завершится неудачей.
Например, в примере ниже произойдет сбой:
@Test(expected=NullPointerException.class)
public void outOfBounds(){
new ArrayList<Object>().get(1);
}
@Ignore
Аннотация @Ignore
указывает игнорировать тест или группу тестов, чтобы избежать потенциального сбоя при выполнении.
Игнорировать тесты можно в двух сценариях:
- игнорировать тестовый метод, помеченный
@Test
. - игнорировать все тесты на уровне класса.
@Ignore
@Test(expected=NullPointerException.class) //obviously wrong test
public void outOfBounds(){
new ArrayList<Object>().get(1);
}
@Before
Методы, помеченные тэгом @Before
, выполняются перед каждым тестом. Это полезно, когда вы хотите выполнить некоторый код перед запуском теста, например, настроить тестовую среду. В Junit5 @Before
был переименован в @beforeEach
, что также работает.
Родственная аннотация @beforeAll
или @BeforeClass
используется, когда перед серией тестов необходимо выполнить дорогостоящую операцию, такую как запуск сервера или внесение изменений в базу данных.
@After
@After
— это противоположность предыдущему тэгу. Все методы, помеченные @After
, будут запущены после теста.
Методы @AfterAll
или @AfterClass
выполняются после выполнения всех тестов класса.
Все методы, аннотированные
@beforeAll
и@afterAll
должны быть статическими, так как выполняются перед запуском тестов класса.
Однако методы
@Before
и@After
не должны быть статическими, иначе компилятор выдаст ошибку.
public class OutputFileTest{ @BeforeAll
public static void startServer() { ... }
@Before
public void createTestLogFile() { ... }
@After
public void deleteTestLogFile() { ... }
@Test
public void test1() { ... }
@Test
public void test2() { ... }
@AfterAll
public static void stopServer() { ... }
}
Код, приведенный выше, выполнится в следующем порядке:
🟢 0️⃣ startServer()
1️⃣ createTestLogFile()
2️⃣ test1()
3️⃣ deleteTestLogFile()
4️⃣ createTestLogFile()
5️⃣ test2()
6️⃣ deleteTestLogFile()
7️⃣stopServer()
🔴
Этот список далеко не исчерпывающий, но он охватывает самые основные аннотации. Воспользуйтесь приведенными выше примерами, чтобы получить представление о лучших практиках в программировании на Java.
Читайте также:
- Когда стоит использовать перечисления в Java?
- Java-библиотеки, которые повысят вашу производительность
- Как правильно учиться Java-программированию: история одного тьютора
Читайте нас в Telegram, VK и Дзен
Перевод статьи: Utkarsh Jain, “Java Annotations 101”