Вопрос по java, exception – Восстановление исключений в Java без потери трассировки стека

368

В C # я могу использоватьthrow; Инструкция для переброса исключения при сохранении трассировки стека:

try
{
   ...
}
catch (Exception e)
{
   if (e is FooException)
     throw;
}

Есть ли что-то подобное в Java (that doesn't lose the original stack trace)?

В C # даthrow e; потеряет трассировку стека. Но не на Яве. Tim Goodman
Я полагаю, что так ведет себя код в .Net, но я больше не уверен. Возможно, стоит поискать его где-нибудь или провести небольшой тест. ripper234
Как вы думаете, почему он теряет оригинальную трассировку стека? Единственный способ потерять его, когда вы генерируете новое SomeOtherException и забываете указать основную причину в конструкторе или в initCause (). akarnokd
Throwableне могут быть изменены, бросая их. Чтобы обновить трассировку стека, вы должны позвонитьfillInStackTrace(), Удобно, чтобы этот метод вызывался в конструктореThrowable. Robert
Некоторые документы от Oracle об исключениях с Java 7:Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking Guillaume Husta

Ваш Ответ

8   ответов
79

try
{
   ...
}
catch (FooException fe){
   throw fe;
}
catch (Exception e)
{
   ...
}
Иногда ловить все исключения в порядке. Например, когда вы пишете контрольный пример. Или для целей регистрации. Или в основном, где не ловить означает сбой.
@Stroboskop: верно, но для ответа лучше всего использовать тот же (аналогичный) код, что и в вопросе!
Этот шаблон хорошо работает для исключений RuntimeException.
Определенно уместно в Java для отлова определенных исключений, кроме generic, и проверки на наличие экземпляров. +1
-1, потому что вы никогда не должны ловить простое & quot; исключение & quot; если вы не знаете, что делаете.
1

если вы переворачиваете пойманное исключение в другое исключение (для получения дополнительной информации) или просто перебрасываете пойманное исключение.

try{ ... }catch (FooException e){ throw new BarException("Some usefull info", e); }

5
public int read(byte[] a) throws IOException {
    try {
        return in.read(a);
    } catch (final Throwable t) {
        /* can do something here, like  in=null;  */
        throw t;
    }
}

IOException,final средстваt может содержать только исключение, выброшенное из блока try. Дополнительный материал для чтения можно найтиВот а такжеВот.

Это не обязательно должно быть окончательным. Увидетьdocs.oracle.com/javase/7/docs/technotes/guides/language/… а такжеstackoverflow.com/a/6889301/131160
22

try
{
   ...
}
catch (Exception e)
{
   if (e instanceof FooException)
     throw e;
}
Я бы добавил конкретный улов для FooException
@MarkusLausberg Но, в конце концов, исключения не обнаруживаются.
В этом конкретном случае я согласен, но добавление определенного улова может быть неправильным выбором - представьте, что у вас есть какой-то общий код для всех исключений, а после, для конкретного исключения, сбросьте его.
Нет, до тех пор, пока вы не создадите новый объект-исключение, трассировка стека останется прежней.
Да, но это был не вопрос.
67

ссировку стека, передав исключение как Throwable в качестве параметра причины:

try
{
   ...
}
catch (Exception e)
{
     throw new YourOwnException(e);
}
Я бы также посоветовал добавить сообщение, используяthrow new YourOwnException("Error while trying to ....", e);
498
catch (WhateverException e) {
    throw e;
}

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

Привет, InterruptedException e выдает необработанное сообщение об исключении, когда я добавляю строку выброса e. Не так, если я заменю его более широким исключением e. Как это должно быть сделано правильно?
Я вижу такой код в Java-проекте, над которым я работаю - это безопасно и безопасно удалить?
@James, я только что заметил, что сообщение исчезнет, если добавить & quot; throws XxxException & quot; в объявлении функции.
@James Если тыcatch(Exception e) { throw e; } это будет необработанным. если тыcatch(InterruptedException ie) { throw ie; } это будет обработано. Как правило, не надоcatch(Exception e) - это не покемон, и мы не хотим поймать их всех!
В Java 7 компилятор для такого перевоспитания более сообразителен. Теперь он отлично работает с определенными "throws" исключения в содержании метода.
5

try 
{
  ...
}
catch (FooException e) 
{
  throw e;
}
catch (Exception e)
{
  ...
}
13

throw e а не простоthrow, Java поддерживает трассировку стека.

Похожие вопросы