Обработка проверенных исключений - PullRequest
4 голосов
/ 12 июня 2011

Я читаю обработку исключений в книге "Руководство программиста по сертификату Java SCJP".Автор пишет, что:

Если в методе выдается проверенное исключение, оно должно обрабатываться одним из трех способов:

1.При использовании блока try и перехватаисключение в обработчике и работа с ним

2. Используя блок try и перехватывая исключение в обработчике, но выбрасывает другое исключение, которое либо не проверяется , либо , объявленное в егоПредложение throws

3. Явно разрешив распространение исключения своему вызывающему, объявив его в предложении throws заголовка его метода

Я ясно понял первое и третьеНо вторая заставила меня сильно запутаться.Мои опасения заключаются в том, что:

-Все все в порядке, даже если я не выбрасываю другие непроверенные исключения, так почему мы должны бросать здесь другое исключение?

-Почему мы имеемповторно объявить исключение, которое мы поймали, в предложении throws?Я думаю, что обработчик закончил.

Спасибо всем.

Ответы [ 5 ]

3 голосов
/ 12 июня 2011

В книге просто перечислены три допустимых варианта.

- Все в порядке, даже если я не выбрасываю другие непроверенные исключения, так почему мы должны бросать здесь еще одно исключение?

Возможно, вы захотите сгенерировать еще одно более описательное исключение, например, добавив больше информации.

-Почему мы должны повторно объявить исключение, которое мы поймали, в броскахстатья?Я думаю, что все кончено обработчиком.

Вам не нужно повторно объявлять.Но если проверяется новое исключение, которое вы выбрасываете, вы должны объявить его в предложении throws.На самом деле исключение, которое вы только что обнаружили, не нужно объявлять, даже если отмечено.

2 голосов
/ 12 июня 2011

Вы можете сделать это, чтобы перехватить проверенное исключение и выдать другое проверенное исключение другого типа. Возможно, вы хотите выбросить собственное исключение, а не другое.

public void doSomething() throws MyCheckedException {
    try {
        doSomethingThatThrowsSpecificCheckedException();
    } catch(SpecificCheckedException e) {
        throw new MyCheckedException();
    }
}

Или вы можете выбросить непроверенное исключение (что-то, что является или расширяется RuntimeException).

public void doSomething() {
    try {
        doSomethingThatThrowsSpecificCheckedException();
    } catch(SpecificCheckedException e) {
        throw new RuntimeException();
    }
}
1 голос
/ 12 июня 2011

Прежде всего, вы должны объявить в предложении throw исключение, которое вы выбросили, а не то, которое вы поймали, при условии, что вы выбросили проверенное исключение.

Во-вторых, вам не нужно этого делать,Это всего лишь один из трех вариантов.

Зачем вы это делаете?Обычно это делается между прикладными уровнями.Например, Hibernate отлавливает SQLExceptions и перебрасывает их как непроверенный HibernateException, так что код, который вызывает методы Hibernate, не должен быть загрязнен try / catches для SQLExceptions.Другой вариант - перевести низкоуровневое исключение в какое-то исключение бизнес-логики, которое может обрабатываться в стеке.Это позволяет лучше изолировать бизнес-логику от деталей реализации низкого уровня.

1 голос
/ 12 июня 2011

Отличный вопрос, и тот, который хорошие программисты java должны обдумать.

Это все о соблюдении сигнатуры метода, которая определяет контракт метода с его вызывающей стороной, и который включает в себя какие исключения вы собираетесь использоватьthrow.

  • Вариант 1 имеет дело с исключением
  • Вариант 2 не имеет отношения к исключению, но сохраняет тот же контракт
  • Вариант 3 не имеет отношения кисключение и изменение вашего контракта

Реализация шаблона в варианте 2 будет:

public interface Server {
    public void useServer() throws ServerException;
}

public class ExplodingClient {
    private Server server = new ServerImpl();
    public void doIt() throws ClientException {
        try {
            server.useServer();
        } catch (ServerException e) {
            // Our contract doesn't allow throwing ServerException,
            // so wrap it in an exception we are allowed by contract to throw
            throw new ClientException(e);
        }
    }
}


public class SilentClient {
    private Server server = new ServerImpl();
    public void doIt() {
        try {
            server.useServer();
        } catch (ServerException e) {
            // Our contract doesn't allow throwing any Exceptions,
            // so wrap it in a RuntimeException
            throw new RuntimeException(e);
        }
    }
}
0 голосов
/ 12 июня 2011

Используя блок try и перехватывая исключение в обработчике, но бросая Другое исключение, которое либо непроверенный или объявленный в его бросках пункт.

Обработка исключений в Java может быть выполнена двумя способами:

  • Завернуть его в блок try-catch-finally.
  • Объявление метода для броска (с использованием throws) исключения вызывающей стороне метода для обработки.

- Все в порядке, даже если я не выбрасываю другие непроверенные исключения, так почему мы должны бросить другой исключение здесь?

Бросить другое исключение означает описать больше об этом. Кроме того, чтобы вызывающий метод знал, что это конкретное исключение было сгенерировано.

-Почему мы должны повторно объявить исключение, которое мы поймали, в бросает оговорку? Я думаю, что все кончено обработчик.

Повторное выделение исключения, которое вы только что перехватили в блоке catch, должно сделать так, чтобы вызывающая сторона этого метода предупредила, что этот метод может вызвать особое исключение. Так что будьте готовы справиться с этим.

Вы должны пройти этот пост Jon Skeet: Sheer Evil: Rethrowing exceptions in Java

Помните, что вы никогда не будете вынуждены обрабатывать непроверенные исключения, компилятор заставляет вас просто перехватить проверенное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...