Java исключения и внутренние исключения, я делаю это правильно? - PullRequest
2 голосов
/ 26 ноября 2011

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

Я считаю, что в Java это называется проверенными исключениями?

SchemaFactory sf = ....

Schema schema = sf.newSchema(...)    // SAXException has to be handled
Validator validator = ...

validator.validate(xmlFile);   // IOException has to be handled again

Как мне писать этот блок кода?

Использую ли я try / catch, вложенный в try / catch?

Ответы [ 3 ]

2 голосов
/ 26 ноября 2011
try {
  SchemaFactory sf = ....

  Schema schema = sf.newSchema(...)    // SAXException has to be handled
  Validator validator = ...

  validator.validate(xmlFile);   // IOException has to be handled again
} catch (SAXException e) {
    // handle SAX error
} catch (IOException e) {
    // handle IO error
}
0 голосов
/ 26 ноября 2011

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

Есть ли у вас другая схема на случай, если используемая вами вызывает исключение Sax? Есть ли у вас другой валидатор, если тот, который вы используете, вызывает исключение IO? Возможно ли другое восстановление за этими исключениями?

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

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

Если ваша стратегия восстановления не удалась, вы можете также превратить исключение восстановления в неконтролируемое исключение, чтобы позволить верхнему уровню обработать его (log + error 500 или что-то в этом роде).

Это принцип безотказной работы.


Обратите внимание, что в Java существуют большие противоречия, которые существуют в течение многих лет по поводу проверенных исключений VS unchecked. Многие влиятельные люди в Java действительно думают, что введение проверенных исключений было ошибкой.

Основными причинами являются:

  • Люди ленивы и склонны ловить исключение не в том месте, чтобы их больше не беспокоили.

  • Люди не следуют рекомендациям Sun: они выдают проверенные исключения, чтобы просто «предупредить» во время компиляции для клиентской части API.

  • Люди склонны думать, что только методы, объявляющие проверенные исключения, могут вызывать исключения, тогда как ЛЮБОЙ код / ​​метод МОЖЕТ генерировать исключения. Вы не должны ловить исключение ТОЛЬКО, КОГДА КОМПИЛЕР СКАЗАЛ ТАК: ВЫ ДОЛЖНЫ ДУМАТЬ, ГДЕ ОНА СООТВЕТСТВУЕТ ПОДПИСАНИЮ.

Вы согласны с Брюсом Экелом:

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

Вы можете найти много ссылок на эту тему. Многие разработчики Java не знают об этом, но многие зрелые фреймворки теперь в основном используют непроверенные исключения (Spring, EJB3 ...).

Также люди, работающие на C # (без проверенных исключений) и Java, склонны думать, что лучше, когда нет проверенных исключений.

Так что вы можете сделать:

try {
    your code here
} catch (Exception e) {
    throw new RuntimeException("optionnal message",e);
}

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


Солнечные источники:

http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Вот основная рекомендация: если клиент может разумно ожидается восстановление после исключения, сделайте его проверенным исключением. Если клиент не может ничего сделать для восстановления после исключения, сделать его непроверенное исключение.

http://docs.oracle.com/javase/specs/jls/se5.0/html/exceptions.html#11.5

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


Брюс Экель (книга «Размышления на Яве»): http://www.mindview.net/Etc/Discussions/CheckedExceptions

«Воспламеняющийся» в предыдущем абзаце - другой вопрос. Теория является то, что если компилятор заставляет программиста обрабатывать исключение или передать его в спецификации исключений, то внимание программиста всегда будет возвращено к возможности ошибок, и поэтому они будут должным образом заботиться о них. я думаю Проблема в том, что это непроверенное предположение, которое мы делаем как Языковые дизайнеры, которые попадают в область психологии. Моя теория является то, что когда кто-то пытается что-то сделать, и вы постоянно подталкивая их с раздражениями, они будут использовать самое быстрое устройство доступны, чтобы эти неприятности уйти, чтобы они могли получить свою вещь сделано, возможно, при условии, что они вернутся и вынут устройство позже.Я обнаружил, что сделал это в первом издании Thinking in Java:

...
} catch (SomeKindOfException e) {}

0 голосов
/ 26 ноября 2011

Я использую try / catch, вложенный в try / catch?

IMO, нет.

try {
    //...
} catch(SAXException e) {
    //handle SAXException
} catch(IOException e) {
    //handle IOException
}

Я думаю, что код выглядит чище, чемс вложенным try / catch.

Как мне писать этот блок кода?

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

public void validateXml() throws SAXException, IOException {
    //...
...