Имеет ли смысл делать «попробуй наконец» без «улова»? - PullRequest
112 голосов
/ 10 апреля 2010

Я видел такой код:

    try
    {
        db.store(mydata);
    }
    finally
    {
        db.cleanup();
    }

Я думал, try должен иметь catch?

Почему этот код делает это так?

Ответы [ 6 ]

161 голосов
/ 10 апреля 2010

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

public void yourOtherMethod() {
    try {
        yourMethod();
    } catch (YourException ex) {
        // handle exception
    }
}    

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}
67 голосов
/ 10 апреля 2010

Это потому, что программист хотел убедиться, что db.cleanup() вызывается, даже если код внутри блока try выдает исключение.Любые исключения не будут обрабатываться этим блоком, но они будут распространяться вверх только после того, как будет выполнен блок finally.

20 голосов
/ 10 апреля 2010

Почему этот код делает это так?

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

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

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

2 голосов
/ 10 апреля 2010

Блок finally гарантирует, что даже при возникновении исключения RuntimeException (возможно, из-за некоторой ошибки в вызываемом коде) будет выполнен вызов db.cleanup().

Это также часто используется для предотвращения слишком большого количестваnesting:

try
{
    if (foo) return false;
    //bla ...
    return true;
}
finally
{
    //clean up
}

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

0 голосов
/ 11 января 2018

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

Блок finally всегда выполняется независимо от того, было ли выброшено исключение.

0 голосов
/ 10 апреля 2010

Код делает это, чтобы гарантировать, что база данных закрыта.
Обычно вы можете поместить весь код доступа к вашей базе данных в блок try, а затем вызвать вызов, чтобы закрыть базу данных в блоке finally.
Способ try ... finally работает, означает, что код в блоке try запускается, а код в блоке finally запускается после его завершения ... несмотря ни на что.
Если не выдернуть компьютер из стены, наконец-то выполнится.
Это означает, что даже если вызвано исключение, и для выполнения метода требуется три года, он все равно перейдет в блок finally и база данных будет закрыта.

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