Перебрасывание исключений в Java - PullRequest
4 голосов
/ 23 февраля 2009

В Java есть возможность перебросить исключение, но есть ли в этом преимущество?

Ответы [ 7 ]

6 голосов
/ 23 февраля 2009

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

5 голосов
/ 23 февраля 2009

Конечно. Если вам нужно выполнить некоторую специальную обработку (ведение журнала, очистку и т. Д.) Для исключения, но вы не можете полностью «обработать» его, обычно выполняют обработку, а затем повторно генерируют исключение. Обратите внимание, что во многих случаях (особенно при очистке ресурсов) вы, вероятно, хотите использовать предложение finally, а не catch / rethrow.

4 голосов
/ 23 февраля 2009

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

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

1 голос
/ 23 февраля 2009

Случаи реального мира

Вот некоторые ситуации в реальном мире, в которых мне нужно было сбросить исключения Java:

  • При выполнении вызова JDBC я бы поймал исключение SQLException. Тем не менее, postgres выдаст исключение PSQLE с дополнительными данными и статусом. В крайних случаях тестирования мы могли повредить базу данных и хотели, чтобы регистратор имел очень конкретные данные об исключении и состоянии. Мы бы обернули исходное исключение в новое исключение, добавив больше данных о состоянии и перезапуске сервера.
  • При реализации синтаксического анализатора текста я бы хотел перехватить ряд исключительных ситуаций при разборе, таких как NumberFormatException, и передать их в стек с дополнительными данными о том, что вызвал текст, и об источнике текста, вызвавшего исключение при разборе.
  • Мой коллега рассказал мне о проекте, в котором он работал, где каждое исключение было заключено в другое исключение одного из двух типов - RetryableException и FatalException. В случае Retryable исключения приложение будет ожидать и повторять операцию через определенный промежуток времени. Я не совсем уверен в том, что я чувствую по поводу этого дизайна, но я вижу в нем временную задержку при решении некоторых транзакционных проблем.
  • В некоторых случаях я использовал бы существующий API, для которого были определены броски, для исключения высокого уровня, и я выполнял бы операцию, которая генерировала бы несвязанное исключение (которое, как я чувствовал, действительно принадлежало как исключение RuntimeException) - тогда я перебросил бы исключение как причину более общего исключения.
  • Самый чистый случай, который я могу вспомнить, когда вы можете захотеть выбросить исключение, это когда вы хотите добавить к нему дополнительные данные. Например:
    public bizMethod() throws CoolBizLogicException {
        int policyId = getPolicyId("bar");
        try {
          coolBizLogic(foobar); // this throws an exception
        }
        catch (CoolBizLogicException cble) {
          cble.setPolicyId(policyId);
          throw cble;
        }
    }
1 голос
/ 23 февраля 2009

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

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

1 голос
/ 23 февраля 2009

Я не занимался Java годами, но насколько я помню, он похож на другие языки с исключениями и ОО. Исключения могут быть разделены на подклассы, и часто вы захотите поймать базовый класс из многих исключений, но, возможно, не сможете обработать все из них. Допустим, вы обрабатываете удаленную передачу файлов и хотите перехватить все ошибки ввода-вывода, потому что вы обрабатываете большинство из них, но не DiskFull. Вы можете перебросить это, и позволить кому-то еще заниматься этим дальше по цепочке, но решить другие проблемы, такие как TransmissionFailed, повторно выполнив передачу.

0 голосов
/ 23 февраля 2009

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

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