2012-05-24 4 views
33

Можно создать дубликат:
Is it possible to detect if an exception occurred before I entered a finally block?В финальном блоке, я могу сказать, если исключение было брошено

У меня есть метод рабочего процесса, который делает вещи, и бросает, если исключение произошла ошибка. Я хочу добавить показатели отчетности в свой рабочий процесс. В нижнем блоке finally, есть ли способ сказать, что один из методов в блоке try/catch сделал исключение?

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

@Override 
public void workflowExecutor() throws Exception { 
    try { 
     reportStartWorkflow(); 
     doThis(); 
     doThat(); 
     workHarder(); 
    } finally { 
     /** 
     * Am I here because my workflow finished normally, or because a workflow method 
     * threw an exception? 
     */ 
     reportEndWorkflow(); 
    } 
} 
+1

Этот вопрос может быть дубликатом предложенного, но это очень сложно сказать, потому что другой вопрос довольно превосходно запутан. Способность определять в конечном блоке, будет ли блок выполняться в рамках обычного потока управления или из-за выброшенного исключения, была бы чрезвычайно полезной, поскольку это упростило бы обработку транзакций; увы, ни Java, ни C# в настоящее время не предлагают эту способность afaik. Позор. –

ответ

47

Не существует автоматического способа предоставления Java. Вы можете использовать логический флаг:

boolean success = false; 
try { 
    reportStartWorkflow(); 
    doThis(); 
    doThat(); 
    workHarder(); 
    success = true; 
} finally { 
    if (!success) System.out.println("No success"); 
} 
3

Вы находитесь там, потому что ваш блок try завершил выполнение. Было ли исключено исключение или нет.

Чтобы различать, когда происходит исключение, или ваше исполнение потока метод успешно завершен, вы можете попробовать сделать что-то вроде этого:

boolean isComplete = false; 
try 
{ 
    try 
    { 
    reportStartWorkflow(); 
    doThis(); 
    doThat(); 
    workHarder(); 
    isComplete = true; 
    } 
    catch (Exception e) 
    {} 
} 
finally 
{ 
    if (isComplete) 
    { 
    // TODO: Some routine 
    } 
} 
5

два решения: вызвать reportEndWorkflow дважды, один раз в catch блоке и один раз в конец try:

try { 
    // ... 
    reportEndWorkflow("success"); 
} catch (MyException ex) { 
    reportEndWorkflow("failure"); 
} 

Или вы можете ввести логическую переменную:

boolean finished = false; 
try { 
    // ... 
    finished = true; 
} finally { 
    // ... 
}