2016-02-08 2 views
1

Я закодировал метод с обработчиком catch-all, но мне нужно перестроить исключение, как если бы оно было необработанным, так что вызывающий (много) дальше столбец вызовов может обрабатывать Это. Тривиальный способ сделать это просто:Перехватить и восстановить необработанное исключение Java

try { 
    ... 
} catch (Exception ex) { 
    // do something here... 
    // and rethrow 
    throw ex; 
} 

Но проблема заключается в том, что из-за throw заявления, Java требует этот метод, чтобы заявить о себе как throws Exception, который, в свою очередь, требует, чтобы все абоненты для обработки исключения или объявить себя throws Exception. И так далее по цепочке звонков ...

Есть ли простой способ перебросить исключение, как если бы текущий метод не обрабатывал его?

+0

Точно так же. Если у вас не было try/catch здесь, ваш метод должен был бы «вызывать исключение» (или, по крайней мере, «throws» типы исключений, фактически брошенных в вызовы метода в блоке 'try'). –

+1

'catch (RuntimeException ex)'. Если ваш код не выдает исключенное исключение, вам понадобится обработчик для «RuntimeException», а другой - для определенных проверочных исключений - оберните в «RuntimeException» и «rethrow». –

+1

«с уловщиком-уловщиком» редко бывает хорошей идеей. Зачем ты это делаешь? – Raedwald

ответ

2

Вы можете сделать то, что сказал @radoh, и просто обернуть его в RuntimeException, но один недостаток этого заключается в том, что ваш стек теперь загрязнен и покажет, что линия нарушения будет там, где вы объявляете throw new RuntimeException(ex).

Альтернативой является использование Lomboks SneakyThrows механизм, как это:

public static void main(String[] args) { 
    methodWithException(); 
} 

private static void methodWithException() { 
    try { 
     throw new Exception("Hello"); 
    } catch (Exception e) { 
     Lombok.sneakyThrow(e); 
    } 
} 

Ваш StackTrace останется неизменным, но вам больше не нужно объявлять throws Exception.

Это стоит почитать documentation о том, почему вы должны/не должны делать этого

+0

SneakyThrow выглядит как раз то, что я хочу - спасибо. И да, я знаю, что это плохо. Я чувствую зло, но другой альтернативой является кодирование jni-библиотеки, которая бросает вызов, не проверяя его компилятор Java. Не хорошо. – adelphus

3

У вас есть ровно два варианта с (проверяемых) исключений:

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

Если вы хотите повторно выдать исключение, как если бы этот метод не поймать его, ваш единственный вариант 2.

Примечание: вы только хотите catch (Exception e) если метод в try блоке на самом деле throws Exception. В противном случае поймайте конкретные типы исключений.

+0

Я бы сделал 2., но существует массивная цепочка вызовов, зависящая от этого метода, которая, в свою очередь, потребует нескольких сотен методов, чтобы все объявили себя как «throws Exception». Не мое развлечение. – adelphus

+2

@adelphus, если это то, что этот метод _do_ (т. Е. Выбрасывает исключение), то это то, что они ** должны ** заявить, что они делают. –

+0

@BoristheSpider ... если метод не является родным. В этом случае он не должен ничего объявлять и может что-то бросить. – adelphus

Смежные вопросы