Sprawdzam nowy kod. Program ma tylko próbę i ostatecznie blokuje. Ponieważ blok catch jest wykluczony, w jaki sposób działa blok try, jeśli napotka wyjątek lub cokolwiek, co można wyrzucić? Czy po prostu przechodzi bezpośrednio do ostatniego bloku?
Sprawdzam nowy kod. Program ma tylko próbę i ostatecznie blokuje. Ponieważ blok catch jest wykluczony, w jaki sposób działa blok try, jeśli napotka wyjątek lub cokolwiek, co można wyrzucić? Czy po prostu przechodzi bezpośrednio do ostatniego bloku?
Odpowiedzi:
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.
Mała uwaga na temat try
/ finally
: Final zawsze będzie wykonywany, chyba że
System.exit()
jest nazywany.try{}
bloku nigdy końców (na przykład pętla bez końca).try{..} catch{ throw ..} finally{..}
? Myślę, że ostatecznie nie zostanie stracony
Specyfikacja języka Java (1) opisuje sposób try-catch-finally
wykonywania. Brak zaczepu jest równoznaczny z brakiem możliwości złapania danego Rzutu.
- Jeśli wykonanie bloku try kończy się nagle z powodu rzutu o wartości V, wówczas istnieje wybór:
- Jeśli typ czasu wykonywania V można przypisać do parametru dowolnej klauzuli catch instrukcji try, to
……- Jeśli typu V w czasie wykonywania nie można przypisać do parametru żadnej klauzuli catch instrukcji try, wykonywany jest ostatni blok . Następnie jest wybór:
- Jeśli ostatni blok kończy się normalnie, instrukcja try kończy się nagle z powodu rzutu o wartości V.
- Jeśli ostatni blok kończy się nagle z powodu S, to instrukcja try kończy się nagle z powodu S (a rzut wartości V jest odrzucany i zapomniany).
Ostatecznie wewnętrzny jest wykonywany przed wyrzuceniem wyjątku do zewnętrznego bloku.
public class TryCatchFinally {
public static void main(String[] args) throws Exception {
try{
System.out.println('A');
try{
System.out.println('B');
throw new Exception("threw exception in B");
}
finally
{
System.out.println('X');
}
//any code here in the first try block
//is unreachable if an exception occurs in the second try block
}
catch(Exception e)
{
System.out.println('Y');
}
finally
{
System.out.println('Z');
}
}
}
Prowadzi do
A
B
X
Y
Z
Ostatni blok jest zawsze uruchamiany po zakończeniu bloku try, niezależnie od tego, czy try kończy się normalnie, czy nienormalnie z powodu wyjątku, eee, rzucanego.
Jeśli wyjątek zostanie zgłoszony przez dowolny kod w bloku try, wówczas bieżąca metoda po prostu ponownie zgłasza (lub nadal zgłasza) ten sam wyjątek (po uruchomieniu ostatniego bloku).
Jeśli ostatni blok rzuca wyjątek / błąd / rzucanie, a istnieje już oczekujący przedmiot do rzucania, robi się brzydki. Szczerze mówiąc, dokładnie zapominam, co się dzieje (tyle z mojego certyfikatu sprzed lat). Myślę, że oba przedmioty miotane łączą się ze sobą, ale jest pewne specjalne voodoo, które musisz zrobić (tj. Wywołanie metody, którą musiałbym podnieść), aby rozwiązać pierwotny problem, zanim „w końcu” zwymiotował, eee, zwymiotował.
Nawiasem mówiąc, spróbuj / w końcu jest dość powszechną czynnością przy zarządzaniu zasobami, ponieważ java nie ma destruktorów.
Np. -
r = new LeakyThing();
try { useResource( r); }
finally { r.release(); } // close, destroy, etc
„W końcu”, jeszcze jedna wskazówka: jeśli nie przeszkadza, aby umieścić w połowu, albo specyficzne catch (spodziewane) Throwable podklasy lub po prostu złapać „Throwable”, nie „Wyjątek” dla ogólnego catch-all pułapkę błędu. Zbyt wiele problemów, takich jak błędy związane z odbiciami, powoduje wyświetlenie „błędów” zamiast „wyjątków”, a te znikną po każdym „złapaniu wszystkiego” zakodowanym jako:
catch ( Exception e) ... // doesn't really catch *all*, eh?
zrób to zamiast tego:
catch ( Throwable t) ...
Wersje Java przed wersją 7 pozwalają na te trzy kombinacje try-catch-last ...
try - catch
try - catch - finally
try - finally
finally
blok będzie zawsze wykonywany bez względu na to, co się dzieje w bloku try
lub / i catch
. więc jeśli nie ma catch
bloku, wyjątek nie będzie tutaj obsługiwany.
Jednak nadal będziesz potrzebować obsługi wyjątków gdzieś w kodzie - chyba że chcesz, aby aplikacja całkowicie się zawiesiła. Zależy to od architektury aplikacji, w której dokładnie znajduje się ten program obsługi.
- Po bloku try Java musi następować blok catch lub last block.
- Dla każdego bloku try może być zero lub więcej bloków catch, ale tylko jeden blok końcowy.
- Ostatni blok nie zostanie wykonany, jeśli program zakończy pracę (albo przez wywołanie System.exit (), albo przez wywołanie krytycznego błędu, który spowoduje przerwanie procesu).
jak działa blok try, jeśli napotka wyjątek lub cokolwiek, co można wyrzucić
Wyjątek jest wyrzucany z bloku, tak jak w każdym innym przypadku, gdy nie jest przechwytywany.
Ostateczny blok jest wykonywany niezależnie od tego, w jaki sposób blok try został zakończony - niezależnie od tego, czy w ogóle są jakieś catch, niezależnie od tego, czy istnieje pasujący catch.
Bloki catch i ostatnie są prostopadłymi częściami bloku try. Możesz mieć jedno lub oba. Z Javą 7 nie będziesz mieć żadnego!
Nie próbujesz tego z tym programem? W końcu zostanie zablokowany i wykonany zostanie ostatni blok, ale wyjątek nie zostanie obsłużony. Ale ten wyjątek można zmienić w ostatnim bloku!
Wewnątrz try
bloku piszemy kody, które mogą zgłosić wyjątek. W catch
bloku obsługujemy wyjątek. finally
Blok jest zawsze wykonywany bez względu na to, czy wyjątek występuje, czy nie.
Teraz, jeśli mamy blok try-final zamiast try-catch-last blok, wtedy wyjątek nie będzie obsługiwany i po bloku try zamiast kontroli będzie przechodził do bloku końcowego. Możemy użyć bloku try-final, gdy nie chcemy nic robić z wyjątkiem.