Когда я создаю новое Исключение, я должен выбросить его или вместо этого поместить в Список? - PullRequest
1 голос
/ 04 апреля 2011

У меня есть проект, в котором я должен анализировать отформатированные данные ASCII. Существует вероятность того, что синтаксический анализатор определит, когда возникнут проблемы с форматированием (ожидаемые не найдены, неожиданные данные найдены) Обычно, если я обнаруживаю ошибку в чем-то, я выбрасываю исключение. Однако на этот раз я хочу продолжить процесс синтаксического анализа и сохранить ошибку синтаксического анализатора в конечном классе. У меня вопрос: можно ли создать новое исключение и просто сохранить его, скажем, в списке, а не бросать, чтобы не останавливать обработку?

Ответы [ 4 ]

6 голосов
/ 04 апреля 2011

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

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

Однако есть хитрый способ/ трюк, который вы можете использовать, чтобы сделать объект исключения менее дорогим для создания экземпляра.Если вы посмотрите на Throwable API, вы заметите, что есть метод с именем fillInStackTrace().Метод вызывается самим конструктором Throwable для захвата кадров стека, и реализация (в Throwable) делает это в некотором родном коде.Однако этот метод не final, поэтому вы можете переопределить его в пользовательском классе исключений, чтобы превратить его в неоперативный.

Вуаля!Конструктор, который работает намного быстрее!Но, конечно, если вам понадобится трассировка стека для исключения, вам не повезло.Поэтому я бы рекомендовал использовать этот хак / трюк очень экономно.

3 голосов
/ 04 апреля 2011

Вы можете сделать следующее:

  • сохранить List проблем (например, список строковых сообщений или список конкретных объектов, содержащих подробности проблемы)
  • в конце, если список не пустой, выведите пользовательское исключение со списком

Например:

List<ParsingProblem> problems = new ArrayList<ParsingProblem>();
while (parsing) {
  ...
  problems.add(new ParsingProblem("some message", someRelevantValue));
}

if (!problems.isEmpty()) {
   throw new ParsingException(problems);
}
3 голосов
/ 04 апреля 2011

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

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

2 голосов
/ 04 апреля 2011

Ничто в спецификации языка или JVM не заставляет вас выдавать Exception, вы можете справиться с этим так же, как с любым другим Object в Java.Так что да, с этой точки зрения очень хорошо вести список Exception объектов.

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

Может быть, вы могли бы избежать этой проблемы, создав Problem и сохранив его в List (и добавление такого объекта в ваш пользовательский Exception).

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