Pytanie Java 7 - Precyzyjne ponowne rzuty z ostatecznym Wyjątkiem


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


21
2017-07-31 11:46


pochodzenie




Odpowiedzi:


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.


24
2017-07-31 11:51



Hey @ jon-skeet, wiem, że jest to + 1-letni post, ale jedna rzecz na ostatniej edycji: w tym scenariuszu, jeśli e nie jest zadeklarowane final, kompilator przyzwyczajenie  niejawnie traktuj to jako final (jak w przypadku wielu połowów). Jednakże, jeśli e odniesienie jest zmienione, a następnie Exception musi być włączone do throws klauzula. - betomontejo
@betomontejo BullsEye. - Kumar Abhinav


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
    }
}

4
2017-08-21 10:04



Związane z: stackoverflow.com/questions/12051791/... - assylias


Bez finału nadal jest poprawna Java. Po prostu tracisz korzyść z tego, że jest "precyzyjny".


0
2017-07-31 11:50



Myślę, że brakuje ci wyrzuconych wyjątków bit of test2 () - it JEST bardziej precyzyjne, więc "wyjątek rzutu" zwykle zawodzi. - Maarten Bodewes