Czy ma sens robić „wreszcie próbę” bez „łapania”?


127

Widziałem taki kod:

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

Myślałem, że trypowinien mieć catch?

Dlaczego ten kod robi to w ten sposób?


1
zapewnia czyszczenie, jak inne wspomniane odpowiedzi, szczególnie w przypadku uchwytów plików fopenlub połączenia z
bazą danych

Odpowiedzi:


182

Jest to przydatne, jeśli chcesz, aby aktualnie wykonywana metoda nadal zgłaszała wyjątek, umożliwiając odpowiednie czyszczenie zasobów. Poniżej znajduje się konkretny przykład obsługi wyjątku od metody wywołującej.

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

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}

17
powszechnie używane z zamkami, jak w: lock.lock (); spróbuj {/ * locked * /} w końcu {lock.unlock ()}
min

Co się stanie, jeśli wyjątek zostanie ostatecznie wrzucony do środka?
barth

1
@barth Gdy nie ma catchbloku, zgłoszony wyjątek finallyzostanie wykonany przed jakimkolwiek wyjątkiem w trybloku. Więc jeśli są dwa wyjątki, jeden w tryi jeden w finallyjedynym wyjątku, który zostanie wyrzucony, to ten w finally. To zachowanie nie jest takie samo w PHP i Pythonie, ponieważ oba wyjątki zostaną wyrzucone w tym samym czasie w tych językach, a kolejność wyjątków to trynajpierw a potem finally.
Deszcz

72

Jest tam, ponieważ programista chciał się upewnić, że db.cleanup()zostanie wywołany, nawet jeśli kod wewnątrz bloku try zgłasza wyjątek. Wszelkie wyjątki nie będą obsługiwane przez ten blok, ale będą propagowane w górę dopiero po wykonaniu ostatniego bloku.


23
+1 Dokładnie. tryJest właśnie tam, aby pozwolić finally. Wyjątki nie są przechwytywane.
zockman

2
+1 za wyjaśnienie, że wyjątek rośnie na stosie, aż zostanie złapany. Dzięki
Code Jockey

20

Dlaczego ten kod robi to w ten sposób?

Ponieważ najwyraźniej kod nie wie, jak obsłużyć wyjątki na tym poziomie. W porządku - tak długo, jak robi to jeden z dzwoniących, tj. Pod warunkiem, że wyjątek zostanie gdzieś obsłużony.

Często kod niskiego poziomu nie może odpowiednio zareagować na wyjątki, ponieważ użytkownik musi zostać powiadomiony, wyjątek musi zostać zarejestrowany lub trzeba wypróbować inną strategię. Kod niskiego poziomu wykonuje jeden tylko funkcję i nie ma informacji o podejmowaniu decyzji na wyższym poziomie.

Ale kod nadal musi wyczyścić swoje zasoby (ponieważ jeśli tego nie zrobi, wycieknie), więc robi to w finallyklauzuli, upewniając się, że tak się dzieje zawsze , niezależnie od tego, czy wyjątek został zgłoszony, czy nie.


2

Ostatni blok zapewnia, że ​​nawet gdy zostanie zgłoszony wyjątek RuntimeException (może z powodu błędu w wywołanym kodzie), db.cleanup() wywołanie zostanie wykonane.

Jest to również często używane, aby zapobiec zbyt dużemu zagnieżdżaniu:

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

Zwłaszcza gdy istnieje wiele punktów, w których metoda zwraca, poprawia to czytelność, ponieważ każdy może zobaczyć, że oczyszczany kod jest wywoływany w każdym przypadku.


0

Kod robi to, aby upewnić się, że baza danych jest zamknięta.
Zwykle sposobem, w jaki można to zrobić, jest umieszczenie całego kodu dostępu do bazy danych w bloku try, a następnie wywołanie zamknięcia bazy danych w bloku final.
Sposób, w jaki try… w końcu działa, oznacza, że ​​kod w bloku try jest uruchamiany, a kod w bloku final jest uruchamiany po zakończeniu… bez względu na wszystko.
Jeśli komputer nie zostanie wyrwany ze ściany, w końcu zostanie wykonany.
Oznacza to, że nawet jeśli zostanie wywołany wyjątek, a wykonanie metody potrwa trzy lata, nadal będzie znajdować się w ostatnim bloku, a baza danych zostanie zamknięta.


0

Jeśli jakikolwiek kod w bloku try może zgłosić sprawdzony wyjątek, musi pojawić się w klauzuli throws podpisu metody. Jeśli zostanie zgłoszony niesprawdzony wyjątek, zostanie on przepuszczony z metody.

Ostatni blok jest zawsze wykonywany, niezależnie od tego, czy został zgłoszony wyjątek, czy nie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.