2013-04-02 10 views
37

Blok "finally" jest zawsze wykonywany, gdy kończy się try-catch, w przypadku wyjątku lub nie. Ale również każda linia kodu na zewnątrz i po próbie catch jest zawsze wykonywana. Dlaczego więc powinienem użyć instrukcji finally?Jaka jest korzyść z używania "finally" po bloku try-catch w java?

Przykład:

try { 
    //code... 
} catch (Exception e) { 
    //code... 
} finally { 
    System.out.println("This line is always printed"); 
} 
System.out.println("Also this line is always printed !! So why to use 'finally'?? "); 
+0

Powinienem był użyć – Aarath

+0

Z catch (Throwable t) zamiast catch (Exception e) ostatnia linia będzie zawsze wykonywana. – Aarath

+1

Jest to częsty wzorzec do zgłaszania nowych wyjątków w blokach catch, a na koniec pozwala wyczyścić elementy z bloku try przed wysłaniem nowego wyjątku. Jest bardzo przydatny. Zapis powoduje również, że kod jest bardziej semantyczny. –

Odpowiedz

21

Najbardziej przydatna sprawa jest, gdy trzeba zwolnić niektóre zasoby:

InputStream is = ... 
try { 
    //code... 
} catch (Exception e) { 
    //code... 
} finally { 
    is.close(); 
} 

Ogólniej go używać, gdy chcemy mieć pewność, że kod jest wykonywany w koniec, nawet jeśli wystąpił wyjątek podczas wykonywania:

long startTime = System.currentTimeMillis(); 
try { 
    //code... 
} catch (Exception e) { 
    //code... 
} finally { 
    long endTime = System.currentTimeMillis(); 
    System.out.println("Operation took " + (endTime-startTime) + " ms"); 
} 

Pomysł tego finally blok zawsze wykonywany jest to, że nie jest w przypadku pierwszej linii po całym bloku

  • jeżeli blok catch pozwala trochę Throwable przepustkę
  • jeśli ponownie generuje się wyjątek, co jest bardzo częste
-2

ostatecznie jedynym celem bloku jest zamknij zasoby, które otworzyłeś wewnątrz bloku try. zasoby mogą być coś podobnego połączenia z bazą danych, w pisaniu pliku/etc czytania:

Connection conn= null; 
try { 
conn= get the db conn; 
//do some DML/DDL 
} 
catch(SQLException ex) { 

} 
finally { 
conn.close(); 
} 
-1

przypuszczać piszesz w pliku i nagle tworzy wyjątek jak zamknąć plik .then wreszcie pomóc i również dla bazy danych transakcja wreszcie blok bardzo pomaga

4

ale także każdą linijkę kodu na zewnątrz i po try-catch jest zawsze wykonywany

to jest błędne. W przypadku niezaznaczonych wyjątków (RuntimeException, Error i ich podklas) kod po finally nie zostanie wykonany.

Spójrz na ten kod

public static void main(String[] args) { 
    try{ 
     someDengerousMethod(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    }finally{ 
     System.out.println("finally block"); 
    } 
    System.out.println("after finally..."); 
} 
public static void someDengerousMethod(){ 
    throw new Error("something went wrong"); 
} 
+0

Przykładowy kod w pytaniu Aaratha przechwyciłby wyjątek RuntimeException. Kod po bloku finally również byłby w tym przypadku uruchamiany. – jarnbjo

+0

@jarnbjo Następnie zamiast "RuntimeException" program może rzucić "Błąd", który również nie jest zaznaczony. Teraz prawdopodobnie powiesz, że można to zrobić chwytając 'Throwable', ale czy tak naprawdę działają prawdziwe programy? Jeśli zaczniemy przechwytywać wszystkie błędy, to naprawdę nie będziemy potrzebować sekcji "w końcu", ponieważ możemy ją przenieść na końcu każdego bloku catch i po sekcji try-catch na wypadek, gdyby nie było wykonywane catch. – Pshemo

+0

Twój problem polega na tym, że próbujesz wyjaśnić ogólne zachowanie za pomocą bardzo wąskiego wyjaśnienia, które obejmuje tylko bardzo konkretną przyczynę. Istnieje kilka sytuacji, w których wykonanie kodu nie będzie kontynuowane poza blokiem finally, np. jeśli jakikolwiek wyjątek zostanie zgłoszony w bloku try i nie zostanie przechwycony z pasującym blokiem catch (nie ma to znaczenia, jeśli jest to wyjątek środowiska wykonawczego lub niesprawdzonego), jeśli nowy wyjątek zostanie zgłoszony w bloku catch lub jeśli wykonywanie kodu zostanie przerwane inne stwierdzenie, np instrukcja return w bloku try. – jarnbjo

0

Blok finally jest kluczowym narzędziem do zapobiegania wyciekom zasobów. Po zamknięciu pliku lub odzyskaniu zasobów należy umieścić kod w ostatnim bloku, aby upewnić się, że zasób jest zawsze odzyskiwany.

Ale w końcu jest przydatny do czegoś więcej niż obsługi wyjątku - to pozwala programistce uniknąć przypadkowego czyszczenia kodu pominięty przez powrót, kontynuować lub zepsuć. Umieszczenie kodu zakończenia w bloku finally jest zawsze dobrą praktyką, nawet jeśli nie są przewidziane wyjątki.

więcej here

6

Ostatni System.out.println (po końcu bloku) będą uruchamiane tylko wtedy, gdy wyjątek wyrzucane w bloku try actuaclly złowionych z bloku zatrzaskowej, a w przypadku wykonania, nie jest przerwany, np instrukcja zwrotu.

W twoim przykładzie, blok finally będzie zawsze uruchamiany, ale wykonanie będzie kontynuowane poza blokiem finally, jeśli nie zostanie przesłany Error w bloku try (nie zostanie przechwycony), jeśli nie zostanie zgłoszony Throwable catch block i nie ma innych instrukcji, które przerywają wykonywanie.

Powiązane problemy