Начните с написания команды try-catch-finally
У исключений есть одна интересная особенность: они определяют область видимости в вашей программе. Размещая код в секции try команды try-catch-finally, вы утверждаете, что выполнение программы может прерваться в любой точке, а затем продолжиться в секции catch.
Блоки try в каком-то отношении напоминают транзакции. Секция catch должна оставить программу в целостном состоянии, что бы и произошло в секции try. По этой причине написание кода, который может инициировать исключения, рекомендуется начинать с конструкции try-catch-finally. Это поможет вам определить, чего должен ожидать пользователь кода, что бы ни произошло в коде try.
Допустим, требуется написать код, который открывает файл и читает из него сериализованные объекты.
Начнем с модульного теста, который проверяет, что при неудачном обращении к файлу будет выдано исключение:
>@Test(expected = StorageException.class)
>public void retrieveSectionShouldThrowOnInvalidFileName() {
> sectionStore.retrieveSection("invalid - file");
>}
Для теста необходимо создать следующую программную заглушку:
>public List retrieveSection(String sectionName) {
> // Пусто, пока не появится реальная реализация
> return new ArrayList();
>}
Тест завершается неудачей, потому что код не инициирует исключения. Затем мы изменяем свою реализацию так, чтобы она попыталась обратиться к несуществующему файлу. При попытке выполнения происходит исключение:
>public List retrieveSection(String sectionName) {
> try {
> FileInputStream stream = new FileInputStream(sectionName)
> } catch (Exception e) {
> throw new StorageException("retrieval error", e);
> }
> return new ArrayList();
>}
Теперь тест проходит успешно, потому что мы перехватили исключение. На этой стадии можно переработать код. Тип перехватываемого исключения сужается до типа, реально инициируемого конструктором FileInputStream, то есть FileNotFoundException:
>public List retrieveSection(String sectionName) {
> try {
> FileInputStream stream = new FileInputStream(sectionName);
> stream.close();
> } catch (FileNotFoundException e) {
> throw new StorageException("retrieval error", e);
> }
> return new ArrayList();
>}
Определив область видимости при помощи структуры try-catch, мы можем использовать методологию TDD для построения остальной необходимой логики. Эта логика размещается между созданием FileInputStream и закрытием, а в ее коде можно считать, что все операции были выполнены без ошибок.