Зачем использовать finally вместо кода после catch [дубликат]



этот вопрос уже есть ответ здесь:




  • Почему мы используем, наконец, блоки?

    9 ответов



почему это



} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
cs.close();
rs.close();
}


вместо



} catch (SQLException sqle) {
sqle.printStackTrace();
}
rs.close();
cs.close();
567   14  

14 ответов:

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

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

кроме того, могут быть и другие исключения вы не поймать - либо потому что вы объявили, что метод бросает их, или потому что они являются непроверенными исключениями. Вы действительно хотите утечка ресурсов, потому что IllegalArgumentException выбросило куда-то?

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

  • код в предложении finally будет выполняться по мере распространения исключения наружу, даже если исключение прерывает остальную часть выполнения метода;

  • код после блока try / catch не будет выполнен, если исключение не будет перехвачено блоком catch и не будет перестроено.

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

согласно HeadFirst Java, блок finally будет запущен, даже если блок try или catch имеет оператор return. Поток переходит к концу, а затем обратно, чтобы вернуться.

ключевое слово finally гарантирует выполнение кода. В вашем нижнем примере операторы close не выполняются. В верхнем примере они выполняются (что вы хотите!)

ваш второй подход не будет делать операторы 'close', потому что он уже покинул метод.

Если вы ловите все ошибки, не должно быть никакой разницы, в противном случае выполняется только код внутри блока finally, потому что последовательность выполнения кода: наконец код - > ошибка броска - > код после улова следовательно, как только ваш код выбрасывает любую необработанную ошибку, только, наконец, блок кода работает так, как ожидалось.

Это способ избежать утечки ресурсов

код в блоке finally будет вызван до того, как исключение будет повторно создано из блока catch. Это гарантирует, что любой код очистки, который вы вложили в блок finally вызывается. Код вне блока finally не будет выполняться.

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

In http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html это вводит в заблуждение (и, возможно, возник вопрос):

The try block of the writeList method that you've been working with here opens a PrintWriter. The program should close that stream before exiting the writeList method. This poses a somewhat complicated problem because writeList's try block can exit in one of three ways.

1. The new FileWriter statement fails and throws an IOException.
2. The list.get(i) statement fails and throws an IndexOutOfBoundsException.
3. Everything succeeds and the try block exits normally.

The 4-й путь (исключение кроме IOException и IndexOutOfBoundsException выбрасывается) отсутствует. Код, изображенный на предыдущей странице, ловит только (1) и (2), прежде чем прибегать к finally.

Я также новичок в Java и имел тот же вопрос, прежде чем найти это статья. Латентная память склонна больше привязываться к примерам, чем к теории в целом.

блок finally может не всегда работать, рассмотрим следующий код.

public class Tester {
    public static void main(String[] args) {
        try {
            System.out.println("The main method has run");
            System.exit(1);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("The finally block has run");
        }
    }
}

в вашем случае я бы предложил обернуть код внутри finally block В try / catch, так как этот код, по-видимому, может вызвать исключение.

    } catch (SQLException sqle) {
        sqle.printStackTrace();
    } finally {
     try {
        cs.close();
        rs.close();
     } catch (Exception e) {
      //handle new exception here
    }

Comments

    Ничего не найдено.