Assertions в Java: практическое руководство по обнаружению багов и обеспечению надежности кода
Assertions в Java
Узнайте, как оператор assert в Java может помочь вам раннее выявлять баги, проверять предположения и улучшать качество кода.
Assertions — это легковесный, только для разработчиков механизм для тестирования условий, которые должны всегда быть истинными во время выполнения. Они включаются явно и исключаются из продакшн-сборок, поэтому никогда не влияют на производительность во время выполнения.
Синтаксис
assert condition;
Здесь condition — булево выражение, которое вы ожидаете, что будет true. Если условие false и assertions включены, JVM выбрасывает AssertionError и останавливает программу.
Включение Assertions
Assertions отключены по умолчанию. Включите их с помощью JVM переключателя:
java -ea:arguments java -enableassertions:arguments
Когда включены, true условие выполняется нормально; false условие вызывает AssertionError и останавливает выполнение.
Пример 1: Базовое утверждение
class Main { public static void main(String args[]) { String[] weekends = {"Friday", "Saturday", "Sunday"}; assert weekends.length == 2; System.out.println("There are " + weekends.length + " weekends in a week"); } }
Вывод с отключенными assertions:
There are 3 weekends in a week
Включение assertions производит:
Exception in thread "main" java.lang.AssertionError
Расширенный синтаксис Assertion
Включите диагностическое сообщение с:
assert condition : expression;
expression передается в конструктор AssertionError и отображается, если условие не выполняется.
Пример 2: Assertion с сообщением
class Main { public static void main(String args[]) { String[] weekends = {"Friday", "Saturday", "Sunday"}; assert weekends.length==2 : "There are only 2 weekends in a week"; System.out.println("There are " + weekends.length + " weekends in a week"); } }
Вывод при включенных:
Exception in thread "main" java.lang.AssertionError: There are only 2 weekends in a week
Целевая активация Assertions
Активируйте assertions для конкретных классов или пакетов:
- Все пользовательские классы:
java -ea - Конкретный класс:
java -ea:AnimalClass Main - Пакет и подпакеты:
java -ea:com.animal... Main - Безымянные пакеты:
java -ea:... Main
Системные классы можно включить с -esa или -enablesystemassertions. Отключение следует схожему паттерну с -da и -dsa.
Когда Assertions ценны
- Недостижимый код: Проверьте, что код, помеченный как недостижимый, действительно недостижим.
void unreachableCodeMethod() { System.out.println("Reachable code"); return; // Недостижимый код System.out.println("Unreachable code"); assert false; } - Отсутствующие default ветви: Обеспечьте исчерпывающую обработку в switch.
switch (dayOfWeek) { case "Sunday": System.out.println("It's Sunday!"); break; case "Monday": System.out.println("It's Monday!"); break; // … default: assert false : dayOfWeek + " is an invalid day"; } - Документирование предположений: Замените хрупкие комментарии на assert операторы, чтобы они оставались в синхронизации.
if (i % 2 == 0) { // ... } else { assert i % 2 == 1 : i; // ... }
Когда не использовать Assertions
- Проверка аргументов публичного API: Пользовательские входы должны вызывать runtime исключения, а не ошибки утверждения.
- Условия с побочными эффектами: Избегайте вызова методов, модифицирующих состояние, внутри assertion, так как код может выполняться молча, когда assertions отключены.
ArrayList<String> weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" )); ArrayList<String> weekends = new ArrayList<>(Arrays.asList("Sunday", "Saturday" )); boolean removed = weekdays.removeAll(weekends); assert removed;
Преимущества Assertions
- Быстрое, разработчик-ориентированное обнаружение багов.
- Автоматически удаляются в продакшн-сборках, обеспечивая нулевую стоимость во время выполнения.
- Уменьшают шаблонный код и проясняют намерение.
- Повышают уверенность при рефакторинге и оптимизации.
java
- Освоение операторов Java: типы, синтаксис и практические примеры
- Комментарии в Java: типы, использование и лучшие практики
- Освоение Java if…else: управление потоком выполнения
- Освоение улучшенного цикла for в Java: синтаксис, примеры и лучшие практики
- Освоение строк в Java: создание, методы и лучшие практики
- Интерфейсы в Java: концепции, реализация и лучшие практики
- Анонимные внутренние классы в Java: определение, синтаксис и практические примеры
- Try-with-resources в Java: автоматическое управление ресурсами
- Аннотации в Java: типы, размещение и практические примеры
- Понимание Java Vector: использование, особенности и сравнение с ArrayList