assertion (утвержение) представляет распространенный паттерн защитного механизма (guard), который позволяет во время тестирования проверить соблюдение некоторых условий. Для поддержки этого механизма в языке Java есть ключевое слово assert.
Оператор assert используется для проверки таких ошибок, при которых нет смысла продолжать программу. Но обычно этот оператор применяется только во время разработки и тестирования, например, для поиска внутренних ошибок программы во время тестирования.
Оператор assert имеет следующие формы:
assert условие; assert условие : выражение;
В обоих формах после оператора assert идет некоторое условие. И среда проверяет истинность этого условия. И если условие не соблюдается, то система генерирует ошибку типа AssertionError
Во второй форме после условия через двоеточие указывается выражение, которое передается в конструктор объекта AssertionError и применяется для создания сообщения об ошибке.
Приведу абстрактные примеры. Первая форма:
assert n > 0;
Здесь оператор assert проверяет, что некоторая переменная n больше 0. Если переменная равна 0 или меньше, что система генерирует ошибку AssertionError
Вторая форма:
assert n > 0 : n;
Здесь фактически все то же самое, только теперь значение переменной n передается в конструктор класса AssertionError и добавляется в сообщение об ошибке.
По умолчанию оператор assert не оказывает никакого действия на работу программы. Ошибка типа AssertionError генериурется, если только при выполнении программы
явным образом включена поддержка assert. Для этого при запуске программы утилите java передается опция -enableassertions или -ea.
Например:
java -enableassertions Program
Также Java позволяет подключать поддержку assert только для определенных классов и пакетов:
java -ea:SomeClass -ea:com.mycompany.somelib... Program
Подвыражение -ea:SomeClass включает assert для класса SomeClass, а -ea:com.mycompany.somelib... - для пакета "com.mycompany.somelib".
Если пакет не имеет имени (пакет по умолчанию), то для подключения assert можно использовать следующее выражение:
-ea:...
При необходимости также можно отключить assert в определенных классах и пакетах с помощью опции -disablessertions или -da:
java -ea:... -da: SomeClass Program
Рассмотрим небольшой пример использования оператора assert:
class Program {
public static void main(String[] args) {
int f1 = factorial(4);
System.out.println("f1: " + f1);
int f2 = factorial(-4);
System.out.println("f2: " + f2);
}
static int factorial(int n){
assert n > 0;
int result = 1;
while(n > 1) result *= n--;
return result;
}
}
Здесь определен метод factorial, который вычисляет факториал числа. Само число передается через параметр. Но по условию факториала число должно быть больше 0. И в самом методе
мы проверяем это условие с помощью assert:
static int factorial(int n){
assert n > 0;
.................
Для демонстрации в методе main() мы два раза вызываем данный метод, передавая в него корректное и некорректное значения:
int f1 = factorial(4); int f2 = factorial(-4);
Скомпилируем программу и выполним ее с флагом -enableassertions:
eugene@Eugene:/workspace/java$ javac Program.java && java -enableassertions Program f1: 24 Exception in thread "main" java.lang.AssertionError at Program.factorial(Program.java:14) at Program.main(Program.java:8) eugene@Eugene:/workspace/java$
И мы видим, что первый вызов метода с корректным значением отработал нормально, а при втором вызове возникла ошибка AssertionError на 14-й строке кода. Поймав
подобную ошибку при тестировании или разработке, мы увидим, что данные, которые в передаются в метод factorial(), не проверяются, и, возможно, при вызове метода добавим код проверки
или какой-нибудь другой механизм, который позволит избежать падения программы.
И дополнительно рассмотрим, что будет при использовании другой формы оператора assert. Для этого изменим немного метод factorial()
static int factorial(int n){
assert n > 0 : n;
int result = 1;
while(n > 1) result *= n--;
return result;
}
В данном случае выражение assert n > 0 : n указывает, что значение параметра n будет передаваться в сообщение об ошибке. Так, при выполнении программы мы получим немного другое сообщение:
eugene@Eugene:/workspace/java$ javac Program.java && java -enableassertions Program f1: 24 Exception in thread "main" java.lang.AssertionError: -4 at Program.factorial(Program.java:14) at Program.main(Program.java:8) eugene@Eugene:/workspace/java$
Теперь из сообщения об ошибке мы видим, что стало причиной ошибки. Ну и естественно мы можем определять более подробные сообщения. Например:
assert n > 0 : "Параметр меньше 1";