Предложение Fail fastfinally в Java
-
09-06-2019 - |
Вопрос
Есть ли способ обнаружить внутри предложенияfinally, что исключение находится в процессе создания?
См. пример ниже:
try {
// code that may or may not throw an exception
} finally {
SomeCleanupFunctionThatThrows();
// if currently executing an exception, exit the program,
// otherwise just let the exception thrown by the function
// above propagate
}
или единственное, что вы можете сделать, это игнорировать одно из исключений?
В C++ он даже не позволяет игнорировать одно из исключений и просто вызывает метод завершения().Большинство других языков используют те же правила, что и Java.
Решение
Установите переменную-флаг, а затем проверьте ее в предложенииfinally, например:
boolean exceptionThrown = true;
try {
mightThrowAnException();
exceptionThrown = false;
} finally {
if (exceptionThrown) {
// Whatever you want to do
}
}
Другие советы
Если вы обнаружите, что делаете это, возможно, у вас проблемы с дизайном.Идея блока «наконец» заключается в том, что вы хотите, чтобы что-то было сделано независимо от того, как завершается метод.Мне кажется, вам вообще не нужен блокfinally, и вам следует просто использовать блоки try-catch:
try {
doSomethingDangerous(); // can throw exception
onSuccess();
} catch (Exception ex) {
onFailure();
}
Если функция выдает ошибку, и вы хотите перехватить исключение, вам придется обернуть функцию в блок try, это самый безопасный способ.Итак, в вашем примере:
try {
// ...
} finally {
try {
SomeCleanupFunctionThatThrows();
} catch(Throwable t) { //or catch whatever you want here
// exception handling code, or just ignore it
}
}
Вы имеете в виду, что хотите, чтобы блок «finally» действовал по-разному в зависимости от того, успешно ли завершился блок «try»?
Если да, вы всегда можете сделать что-то вроде:
boolean exceptionThrown = false;
try {
// ...
} catch(Throwable t) {
exceptionThrown = true;
// ...
} finally {
try {
SomeCleanupFunctionThatThrows();
} catch(Throwable t) {
if(exceptionThrown) ...
}
}
Однако это становится довольно запутанным...возможно, вы захотите подумать о том, как реструктурировать свой код, чтобы сделать это ненужным.
Нет, я так не думаю.Блок catch завершится до завершения блокаfinally.
try {
// code that may or may not throw an exception
} catch {
// catch block must exist.
finally {
SomeCleanupFunctionThatThrows();
// this portion is ran after catch block finishes
}
В противном случае вы можете добавить объектsync(), который будет использовать код исключения, который вы можете проверить в блокеfinally, что поможет вам определить, запускаете ли вы исключение в отдельном потоке.