2014-09-28 13 views
9

, więc mam trochę kodu tutaj i nie jestem pewien całkowicie, w jaki sposób zareagowałby w przypadku, gdy metoda read.close() zgłasza wyjątek.Czy w końcu całkowicie wykonać, jeśli wyjątek jest wrzucony w końcu bloku

public void someMethod(String s) throws IOException{ 
    BufferedReader reader = Files.newBufferedReader(filePath,cs); 
    listRWLock.readLock().lock(); 
    try{ 
    //miscellaneous code involving reading 
    }finally{ 
    reader.close() 
    listRWLock.readLock().unlock() 
    } 
} 

ListRWLock jest ReentrantReadWriteLock. W przypadku, gdy metoda read.close() zgłasza wyjątek, czy instrukcja po tym nie zostanie wykonana? Próbowałem już wyszukać temat i chociaż uzyskałem coś o ostatecznym wykonaniu w przypadku instrukcji return, nie udało mi się znaleźć szczegółów na temat tego, co się stanie, jeśli wyjątek zostanie zgłoszony w bloku finally.

Z góry dziękuję.

+1

Kolejne wypowiedzi nie powinny wykonywać. Również 'return' w bloku' finally' może przesłonić poprzednie wyjątki. –

Odpowiedz

4

Zasadniczo, wreszcie klauzule są tam, aby zapewnić prawidłowe uwalnianie zasobu. Jednakże, jeśli wyjątek zostanie wrzucony do bloku finally, gwarancja ta zniknie.

Problemem, dla którego nie ma naprawdę zadowalającego rozwiązania, jest to, że kod w bloku finally może sam rzucić wyjątek. W tym przypadku wyjątek w bloku finally zostanie wyrzucony z wyjątku zamiast jakiegokolwiek wyjątku występującego w bloku try. Ponieważ kod w bloku finally jest przeznaczony do „oczyszczania” kod, możemy zdecydować się traktować wyjątki występujące tam jako wtórne i umieścić excplicit haczyk:

public int readNumber(File f) throws IOException, NumberFormatException { 
    BufferedReader br = new BufferedReader(new 
    InputStreamReader(new FileInputStream(f), "ASCII")); 
    try { 
    return Integer.parseInt(br.readLine()); 
    } finally { 
    try { br.close(); } catch (IOException e) { 
     // possibly log e 
    } 
    } 
} 

kilka innych rzeczy, aby pamiętać o końcu bloki:

  1. ten sam „nadrzędny” problem, który możemy wymienić z wyjątkami występuje po powrocie wartości z bloku finally: to byłoby zastąpić dowolną wartość powrotną, że kod w bloku try chciał zamian. W praktyce zwracanie wartości z klauzuli finally jest rzadkie. i niezalecane.
  2. Właściwie wyjście z programu (albo dzwoniąc System.exit() lub przez powoduje błąd krytyczny, który powoduje przerwanie procesu: czasami mowa nieformalnie jako „hotspot” czy „Dr Watson” w systemie Windows) będzie uniemożliwić wykonanie blokady!
  3. Nie ma nic, co mogłoby powstrzymać nas od zagnieżdżania bloków try/catch/finally (na przykład , umieszczenie bloku try/finally wewnątrz bloku try/catch, lub na odwrót), a nie jest to rzadkie.
+0

Bezpośrednio skopiowałeś i miszczyłeś swoją odpowiedź z [tutaj] (http://www.javamex.com/tutorials/exceptions/exceptions_finally.shtml) i [tutaj] (http://softwareengineering.stackexchange.com/a/ 188877/114810)? Biorąc jedno zdanie z każdego z nich! Miej przyzwoitość, aby przynajmniej dać im kredyt! –

1

powinien to sprawdzić,

ale jeśli próba rzuca IO wyjątku, potem czytnik przyzwyczajenie bliskie.

Może mieć

catch(IOException ex){ 
     reader.close() 
+0

Niepoprawnie i nie odpowiada na pytanie. – EJP

1

Wyjątek może zdarzyć się w dowolnym miejscu w kodzie, w tym finally bloku, więc trzeba go złapać, jak nigdzie indziej w kodzie. Sprawdź następujące stanowisko aby uzyskać kilka pomysłów na temat sposobów można obsłużyć taką sytuację:

throws Exception in finally blocks

+0

Nie odpowiada na pytanie. – EJP

4

można zrobić coś takiego:

try{ 
    //miscellaneous code involving reading 
}finally{ 
    handlePossibleException(reader); 
    listRWLock.readLock().unlock() 
} 

handlePossibleException(BufferedReader reader) { 
    try { 
     if (reader != null) { 
      reader.close(); 
     } 
    } catch(Exception e) { 
     log.e("reader.close() Exception: ", e); 
     } 
} 
Powiązane problemy