W poprzednich wersjach java ponowne wyrzucanie wyjątku było traktowane jako rzucanie typu parametru catch.
Na przykład:
public static void test() throws Exception{
DateFormat df = new SimpleDateFormat("yyyyMMdd");
try {
df.parse("x20110731");
new FileReader("file.txt").read();
} catch (Exception e) {
System.out.println("Caught exception: " + e.getMessage());
throw e;
}
}
W języku Java 7 możesz dokładniej określić zgłaszany wyjątek, jeśli zgłosisz wyjątek final
:
//(doesn't compile in Java<7)
public static void test2() throws ParseException, IOException{
DateFormat df = new SimpleDateFormat("yyyyMMdd");
try {
df.parse("x20110731");
new FileReader("file.txt").read();
} catch (final Exception e) {
System.out.println("Caught exception: " + e.getMessage());
throw e;
}
}
Moje pytanie: Doktorzy mówią, że muszę zadeklarować wyjątek final
. Ale jeśli nie, powyższy kod nadal się kompiluje i działa. Czy czegoś brakuje?
Referencje:
Project Coin: multi-catch i final rethrow
Dodaj więcej elastycznych sprawdzeń w poszukiwaniu wyjątków odrzuconych
ja uwierzyć Widziałem tweeta od Josha Blocha, który powiedział, że "ostateczne" ograniczenie zostało zniesione z opóźnieniem. Zobaczę, czy mogę znaleźć wpis na ten temat, ale podejrzewam, że po prostu "wczesna" dokumentacja, którą czytasz, jest teraz niedokładna.
EDYCJA: Nie mogę znaleźć dokładnego wpisu "zmienił się", ale Dokumentacja Java 7 stwierdza pokazuje przykład z nim nie być ostatecznym. Mówi o byciu zmiennymi wyjątku niejawnie końcowy, gdy blok catch deklaruje więcej niż jeden typ, ale to jest nieco oddzielne.
EDYCJA: Teraz znalazłem źródło mojego zamieszania, ale jest to wewnętrzna lista mailingowa :( W każdym razie, nie musi być zadeklarowana jako ostateczna, ale uważam, że kompilator traktuje to jako niejawnie końcowy - tak jak w scenariuszu z wieloma połowami.
Powód, dla którego obie kompilacje jest taka, że wyjątek w klauzuli catch uni, która nie jest później modyfikowana, jest pośrednio ostateczny (JLS 14.20).
Tak więc, aby Twój przykład się nie kompilował, musisz w jakiś sposób zmodyfikować e, na przykład:
public static void test2() throws ParseException, IOException {
DateFormat df = new SimpleDateFormat("yyyyMMdd");
try {
df.parse("x20110731");
new FileReader("file.txt").read();
} catch (Exception e) {
if (e instanceof ParseException) {
e = new ParseException("Better message", 0);
} else {
e = new IOException("Better message");
}
System.out.println("Caught exception: " + e.getMessage());
throw e; //does not compile any more
}
}
Bez finału nadal jest poprawna Java. Po prostu tracisz korzyść z tego, że jest "precyzyjny".