7. Исключения
Исключение (исключительная ситуация, exception) - это ненормальная ситуация в логике приложения. К примеру, метод считывает страницы с нескольких сайтов. В идеальном мире этот метод работал бы без всяких "но", однако в реальности у пользователя может оборваться соединение, тогда метод не может быть работоспособным. Это исключительная ситуация. Такие ситуации нужно отлавливать и правильно обрабатывать.
Исключения решают следующие проблемы:
1. Неоднозначность возвращаемых значений. К примеру, этот метод добывает число из строки:
Integer.parseInt("fff");
Что мы должны возвращать в данном случае, если не будет никаких исключений? 0? Но, ведь, туда и "0" могли передать, как тогда определить отработала ли функция верно или нет?
2. Информативность. К примеру, метод работает с сетью и может выбрасывать
ConnectionRefusedException при разрыве соединения. Если бы он не был помечен как throws
ConnectionRefusedException, разработчик может и не подумать о том, что такая ситуация может произойти, а произойти она может через месяц, когда программу показывают заказчику :)
3. Неработоспособность объекта. К примеру, есть объект, который из БД выбирает Пользователей. Его используют другие объекты. При инициализации ему подсунули неправильный URL к базе. Этот объект не может выполнять свои функции. Что прикажете с ним делать? Он должен выбросить исключение, ибо он битый.
4. ШопНеЗабытьИсключение. Часто бывает необходимость реализовать метод какого-либо интерфейса, который, собственно, пока не особо нужен и тратить на него время не хочется. Однако возможно кто-то другой захочет этот метод вызвать. Чтоб не вышло ситуации, когда разработчик по несколько часов сидит перед монитором, не понимая, почему метод возвращает неправильные значения или не изменяет состояние объекта(были реальные случаи!), лучше всего не оставлять тело метода пустым, а выбрасывать UnsupportedOperationException.
Существует два вида исключений:
- Checked exceptions - это исключения, которые вызовут ошибку компиляции, если не обрамить их с помощью try-catch.
- Unchecked exceptions - те исключения, которые не обязательно отлавливать. Эти исключения должны быть описаны в комментариях, иначе как пользователь ваших классов узнает о его существовании? Эти исключения позволяют сократить количество строк кода и улучшить его читабельность, однако применять его где нипопадя нельзя. Есть несколько случаев, когда следует использовать этот вид исключений:
- Когда исключение может возникнуть по халатности разработчика. К примеру, IndexOutOfBoundException возникнет в случае, если программист неправильно оформит цикл, NullPointerException - если обратиться к null-ссылке.
- В последнее время пошла мода выбрасывать RuntimeException в случае возникновения критических ошибок в приложении. К примеру, если в файлах свойств была прописан неверный user-password к БД, то приложение не сможет продолжать работать. Обработать правильно такое исключение в большинстве случаев не представляется возможным, посему может быть уместным использовать именно эти исключения.
- Подробней о том, какие исключения когда лучше использовать можно прочитать в статье Barry Ruzek'а
Синтаксис отлавливания исключений может включать блок finally:
try {
someObject.someMethod();
} catch(SomeException e) {
logger.warning("Some exception occured", e);
} finally {
//some finalizations
}
Блок finally будет выполняться независимо от того выбросилось ли исключение или нет. Служит он для того, чтоб, к примеру, закрыть соединение к файлу. Ведь, соединение должно закрыться в любом случае - произошло ли чтение из него с ошибками или без, в противном случае придем к утечки памяти из-за незакрытых ресурсов.
Описание типичный исключений в Java можно найти
здесь.