2009-07-10 18 views
7

Rozważmy następujący kodsprawdzone niezaznaczone wyjątkami

private int meth() 
{ 
    try 
    { 
     return 1; 
    } 
    catch(Exception ex) 
    { 
     return 2; 
    } 
    finally 
    { 
     return 3; 
    } 
} 

Gdy kod aforeseen jest sporządzany „wyjątek” traktuje się jako niekontrolowany wyjątku. To jest „nieosiągalny blok catch wyjątek nie zostanie zgłoszony w bloku try” Błąd kompilacji nie occur.Consider Jestem deklarując własne wyjątek,

class MyException extends Exception 
{ 
} 

i używanie go w kodzie

private int meth() 
{ 
    try 
    { 
     return 1; 
    } 
    catch(MyException me) 
    { 
     return 2; 
    } 
    finally 
    { 
     return 3; 
    } 
} 

W ten "nieosiągalny blok catch" wyjątek MyException nigdy nie jest zgłaszany w bloku try "Wystąpił błąd kompilacji. Dlaczego w pierwszym scenariuszu "wyjątek" jest traktowany jako wyjątek RuntimeException, a w drugim scenariuszu, mimo że "MyException" jest podklasą "wyjątku", jest traktowany jako sprawdzany wyjątek. Czy ktoś może mi pomóc w rozwiązaniu tego problemu?

Odpowiedz

4

Jeśli chodzi o kompilator wie, że w dowolnym momencie można uzyskać wyjątek przepełnienia stosu, wyjątek pamięci, wyjątek arytmetyczny lub dowolną liczbę innych wyjątków generowanych przez JVM. Z drugiej strony może statycznie analizować blok try i widzieć, że MyException nigdy nie jest rzucany, więc podrzuca ręce do góry. Wie, że nigdy nie zostanie rzucona przez JVM.

+0

To byłoby moje przypuszczenie - że ponieważ traktuje wyjątki JVM jako wyjątek, który może być rzucony - ale wie, że wyjątek zdefiniowany przez użytkownika nie mogą być wyrzucane, chyba że istnieje „rzucać” zadzwonić gdziekolwiek w próbie. – nlaq

12

Powodem takiego zachowania jest to, że tylko niesprawdzonych wyjątki w języku Java jest RuntimeException i to podklasy. Wszystkie inne wyjątki i błędy, w tym twoje, ponieważ zawiera ona tylko podklasy wyjątek (a nie RuntimeException) są sprawdzane wyjątki.

Powodem, dla którego pierwszy przykładowy kod nie jest oflagowany przez kompilator, mimo że używa on klasy Exception jako instrukcji catch, jest z powodu hierarchii klas. Ponieważ wszystkie wyjątki wywodzą się z wyjątku, to kod nie chwyta wyjątku, ale przechwytuje wszystkie wyjątki i rzuca je do wystąpienia wyjątku. W związku z tym kompilator nie może stwierdzić, czy wyjątek, który zostanie przechwycony w środowisku wykonawczym, jest zaznaczonym lub niezaznaczonym wyjątkiem. W drugim bloku kodu nie ma możliwości, aby wyjątek, który został przechwycony, nie był sprawdzanym wyjątkiem, dlatego kompilator może określić, że blok catch jest niedostępny.

+0

Rzeczywiście lepsza odpowiedź. +1 –

+0

+1 - Chciałem napisać tylko, że ... spojrzeć na hierarchii wyjątek od spadków ... 's wszystko :-) – Newtopian

1

W Java, niezaznaczone (Wyjątki w czasie wykonywania) i sprawdzony wyjątek wszystkie pochodzą z wyjątku.

W twoim przykładzie, w pierwszym przypadku, blok catch może albo złapać wyjątek RuintimeException (otrzymujesz tutaj wątpliwość) lub dowolny zaznaczony wyjątek, a tym samym nie narzekać na wyjątek, który nie został złapany.

Jednak w tym drugim przypadku, ponieważ zostały wyraźnie wymienione typ wyjątku, który jest sprawdzany, a które nie są wyrzucane w dowolnej części kodu, a tym samym daje błąd. Ten blok catch nie dotyczy RTExceptions.In tym konkretnym przypadku, nie uzyskać korzyści z wątpliwości, które kompilator miał w swoim pierwszym scenariuszu.

Powiązane problemy