2014-10-18 2 views
3

У меня довольно много опыта работы с Java (математика, пользовательские интерфейсы и графика в основном), но я никогда серьезно не работал с такими API, как JDBC или org.w3c.dom, где вы в значительной степени полагались на обработку проверенных исключений во время выполнения. Поэтому, если я пишу кучу методов, которые волнуют эти API-интерфейсы, как я могу решить, что делать с исключениями, следует ли сразу их поймать или добавить их в подпись метода и таким образом убрать исключения на более высокий уровень кадра стек, где все они обрабатываются? Кажется, что все, что я хотел бы сделать с этими проверенными исключениями, - это выйти из приложения с ошибкой всякий раз, когда встречается.Как решить, следует ли добавлять исключение к сигнатуре метода или обрабатывать его в методе?

ответ

3

Как правило, исключения делятся на два ведра: 1) тип можно восстановить с каким-то значимым образом. 2) тип, указывающий на отказ и, возможно, необходимость сообщить об этом (протоколирование, возврат страницы с ошибкой, отображение диалога и т. Д.).

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

Исключения, связанные с валидацией в веб-приложениях, являются хорошим примером того типа, который вы не обрабатываете, и вместо этого вы позволяете веб-приложению улавливать их, а затем сопоставлять их с кодом ответа статуса 400.

Другой пример: Java выбрасывает исключенное исключение практически для всего, что принимает кодировку символов. Обычно вы просто хотите перейти в «utf-8», и если вы не ошибетесь, это исключение никогда не произойдет. Если это произойдет, значит, UTF-8, по-видимому, больше не поддерживается. Я не понимаю, как вы могли бы оправиться от этого значимым образом. Я склоняюсь к тому, чтобы поймать и вернуть их в качестве непроверенных исключений. Они никогда не произойдут, но когда они это сделают, я хочу, чтобы программное обеспечение терпело неудачу с исключением, чтобы он где-то регистрировался.

Итак, если какой-либо код, который вы используете, генерирует исключенное исключение, вам нужно решить, можете ли вы восстановить его локально. Если нет, вам нужно решить, нужно ли кому-то из стека вызовов/знать или обрабатывать исключение. Если это так, добавьте его в свои броски и переместите решение в стек вызова. Если нет, сверните его как исключенное исключение и обработайте его где-нибудь централизованно (например, запишите его).

2

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

Для серверной программы, однако, это не будет хорошей стратегией. Например, вы не хотите, чтобы ваш сервер терпел сбои всякий раз, когда БД недоступна из-за короткой сетевой проблемы.

1

Ну, это сложный вопрос. Один из пяти критериев модульности из книги Б.Мейера - это защита. Этот критерий говорит, что если ошибка возникает в классе или модуле, он не должен распространяться в дырочной системе . Поэтому ошибка должна быть изолирована от другого компонента системы.

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

1

Если исключение указывает на проблему, вызванную внешними источниками, такими как проблема с сетью, плохой формат xml и т. Д. (Зависит от типа исключения). то вы должны поймать такое исключение, где вы можете что-то с этим сделать - если это приложение GUI, а затем поймать его, где вы можете показать диалог ошибок пользователю, - и заставить его/ее принять решение. Если это на сервере, то ошибка журнала - вернуть его клиенту. Если исключение вызвано ошибкой программирования, то в приложении GUI вы можете зарегистрировать его/или разрешить пользователю отправлять его по электронной почте пользователю. Для инструмента командной строки я бы разрешил приложению выходить с исключением и выкидывать все свои данные для вывода, если это приложение GUI - я бы скорее попытался поймать его и попытаться восстановить, указав пользователю, что есть проблема.

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

2

Этот вопрос немного сложно ответить.

Допустим, вы идете на рынок, чтобы что-то купить, но у вас нет наличных денег в вашем камердинере. У вас есть банкоматная карта какого-то банка, но опять же вы не уверены в том, достаточно ли денег на вашем счете, чтобы делать покупки.

Теперь здесь есть две вещи. Либо,

1) Вы сначала убедитесь, что у вас есть достаточно денег на вашем счете, прежде чем выходить на рынок, или

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

Кроме того, в Java есть два типа исключений

Checked Exception which is a sub-class of java.lang.Exception, and 
Unchecked Exception which is a sub-class of java.lang.RuntimeException. 

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

Аналогичным образом, неконтролируемое исключение можно рассматривать как вы идете на рынок, не зная о балансе в своем аккаунте. Теперь на счетчике счетов ваша транзакция будет успешной. ИЛИ будет отклонен, потому что у вас недостаточно баланса в вашем аккаунте. Здесь также, вы можете решить только извиниться перед владельцем магазина и пойти или вы можете позвонить кому-нибудь, чтобы принести необходимые деньги в магазин.

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

Аналогичным образом, при программировании на Java не существует большой разницы между Исключенным и Непроверенным Исключением и тем, что вы хотите сделать, если Исключения произошли, полностью зависит от ваших личных/организационных политик.

Компилятор Java обязывает это в случае, если метод выбрасывает проверенное исключение, ваш код с использованием этого метода должен поймать Исключение ИЛИ выбросить его на один уровень вверх. Если в случае Unchecked Exceptions это необязательно.

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

// Here compiler makes sure that you either catch exception OR declare it to be thrown 
public void storeDataFromUrl(String url){ 
    try { 
     String data = readDataFromUrl(url); 
    } catch (BadUrlException e) { 
     e.printStackTrace(); 
    } 
} 

// Here BadUrlException is a subclass of Exception  
public String readDataFromUrl(String url) throws BadUrlException{ 
    if(isUrlBad(url)){ 
     throw new BadUrlException("Bad URL: " + url); 
    } 
    String data = null; 
    //read lots of data over HTTP and return it as a String instance. 
    return data; 
} 

Теперь ваш storDataFromUrl() метод может либо поймать BadUrlException или он может объявить его б бросок, в этом случае код, используя StoreDataFromUrl() метод должен будет сделать то же самое. То есть, либо поймать исключение, либо бросить его для кого-то выше, чтобы справиться с ним, как они хотели бы.

И теперь тот же пример, который выдает исключение Unchecked;

// Here compiler does not force you to either catch exception OR declare it to be thrown 
public void storeDataFromUrl(String url){ 
     String data = readDataFromUrl(url); 
} 

// Here BadUrlException is a subclass of RuntimeException  
public String readDataFromUrl(String url) { // Notice, it does not have a throws clause 
    if(isUrlBad(url)){ 
     throw new BadUrlException("Bad URL: " + url); 
    } 
    String data = null; 
    //read lots of data over HTTP and return it as a String instance. 
    return data; 
} 

НЕСКОЛЬКО ПУНКТОВ Большинство советов книги вы использовать проверенные исключения для всех ошибок приложение может оправиться от и непроверенных исключений для ошибок приложение не может оправиться.

На самом деле большинству приложений придется восстанавливать почти все исключения, включая NullPointerException, IllegalArgumentExceptions и многие другие исключенные исключения. Не удалось выполнить действие/транзакцию, но приложение должно остаться в живых и быть готовым к выполнению следующего действия/транзакции. Единственный раз, когда обычно законно закрывать приложение, во время запуска. Например, если файл конфигурации отсутствует, и приложение не может сделать ничего разумного без него, тогда законно закрыть приложение.

EDIT: Yo может прочитать эти две статьи для большего понимания по теме: Three rules for effective exception handling и Best Practices for Exception Handling