2015-08-13 27 views
12

Dlaczego throw outerE; generuje błąd kompilacji? Wiem, że throw e; nie powinny generować błąd kompilatora powodu precise rethrow feature.Dlaczego którekolwiek z tych odrzuconych wyjątków powodują błąd kompilatora?

to ta sama Exception obiekt, ale jedno jest zawężona wewnątrz bloku catch tylko jeden i jest określania zakresów zewnątrz bloku try-catch.

Czy żaden z nich nie powinien generować błędu kompilatora? A przynajmniej obie zachowują się w ten sam sposób?

static void preciseRethrowTest() 
{ 
    Exception outerE; 
    try 
    { 

    } 
    catch (Exception e) 
    { 
     outerE = e; 

     // Compilation error here. Unhandled exception type Exception 
     // throw outerE; 

     throw e; // No compiler error 
    } 
} 

Używam Java 1.8.0_51. (Pretse rethrow został wprowadzony w języku Java 7)

Odpowiedz

6

Twoja metoda nie ma deklaracji throws.

Kompilator jest teraz wystarczająco inteligentny, aby stwierdzić, że Twój blok try nie może wyrzucić żadnych sprawdzonych wyjątków. Dlatego wszelkie wyjątki przechwycone i powiązane z parametrem Exception w twoim bloku catch muszą być odznaczone. Ponieważ nie są zaznaczone, możesz je ponownie zagospodarować w czasie wolnym (i nie będą wymagały deklaracji throws).

Tutaj próbują przypisać

outerE = e; 
// Compilation error here. Unhandled exception type Exception 
// throw outerE; 

i przekaż wyjątek przez inną zmienną. Kompilator nie posuwa się tak daleko, aby dowiedzieć się, jaka jest wartość w outerE. Może to być wyjątek w twoim złapaniu lub może być czymś innym. Kompilator odtwarza go bezpiecznie i nie pozwala tego zrobić.

Rozważmy kod jak

if (Math.random() < 0.5) 
    outerE = e; 
else 
    outerE = new IOException("nope"); 
throw outerE; 

Nie ma mowy o kompilator wiedzieć, czy wartość Exception przechowywane w outerE jest niesprawdzony wyjątek złapałeś lub innego, potencjalnie zaznaczone, wyjątek przypisany gdzieś indziej.

1

Problem polega na tym, że blok catch nie może zostać osiągnięty przez sprawdzone wyjątki; kompilator jest wystarczająco inteligentny, aby to zrozumieć.

Rozważ to:

public class RethrowTest { 
    static void preciseRethrowTest() { 
    Exception outerE; 
    try { 
     throw new Exception(); 
    } catch (Exception e) { 
     outerE = e; 

     // Compilation error here. Unhandled exception type Exception 
     // throw outerE; 

     throw e; // Now a compiler error *is* generated. 
    } 
    } 
} 

Ten robi rzucać błąd kompilatora, ponieważ kod może zostać osiągnięty za pomocą sprawdzonej wyjątku teraz.