Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2014
    Messaggi
    55

    Gestione delle eccezioni Java

    Salve a tutti,
    ho bisogno di un chiarimento per quanto rigurda la gestione delle ecezioni in java.
    Se trovo un throw (new Eccezione) in un blocco finally, che succede?
    Il compilatore si ferma e da sempre e in ogni caso errore di compilazione oppure va a cercare il catch dell'eccezione nella funzione che ha richiamato la funzione che ha generato l'errore? e se tale funzione è il main?

    qui ad esempio:
    codice:
    class MyExc1 extends Exception { }
    class MyExc2 extends Exception { }
    class MyExc3 extends MyExc2 { }
    public class D1 {
    public static void main(String[] argv){
    try {
    p();
    }
    catch( MyExc2 k ) {}
    finally {
    System.out.print(1);
    throw( new MyExc2() );
    }
    }
    
    static void p() {
    try {}
    catch( MyExc1 s ) {
    System.out.print(2);
    }
    catch( MyExc3 k ) {
    }
    catch( Exception u ) {}
    finally {
    System.out.print(3);
    throw( new MyExc3() );
    }
    }
    }
    Il compilatore darà errore di compilazione ma...per quale preciso motivo?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Lodin Visualizza il messaggio
    ho bisogno di un chiarimento per quanto rigurda la gestione delle ecezioni in java.
    Se trovo un throw (new Eccezione) in un blocco finally, che succede?
    Il compilatore si ferma e da sempre e in ogni caso errore di compilazione oppure va a cercare il catch dell'eccezione nella funzione che ha richiamato la funzione che ha generato l'errore? e se tale funzione è il main?
    Facciamo prima una premessa. Un metodo ha sempre e solo UNA "ragione" di uscita. O esce normalmente con un valore di ritorno oppure esce per una eccezione lanciandola fuori.

    Due scenari abbastanza "eloquenti":

    codice:
    public static int prova() {
        try {
            return 10;
        } finally {
            throw new RuntimeException("Eccezione!");
        }
    }

    Qui (forse) penseresti che il metodo esce normalmente restituendo 10. NO. Quando arriva al return 10, questa è la prima "ragione" di uscita e la mantiene per il momento. Poi però c'è il finally che deve essere onorato. Ma il finally lancia un RuntimeException. La prima ragione di uscita (il return di 10) viene buttata via e il metodo esce quindi per la eccezione, la seconda e ultima ragione di uscita.

    Altro caso opposto:

    codice:
    public static int prova() {
        try {
            throw new RuntimeException("Eccezione!");
        } finally {
            return 10;
        }
    }

    Quando si arriva al throw .... il lancio di RuntimeException è la prima "ragione" di uscita e viene tenuta per buona per il momento. Ma idem c'è un finally che deve essere eseguito. Ma il finally restituisce 10. Quindi la prima ragione di uscita viene buttata via e il metodo ritorna con l'ultima ragione di uscita, che è la restituzione di 10.

    Quote Originariamente inviata da Lodin Visualizza il messaggio
    qui ad esempio:
    Il compilatore darà errore di compilazione ma...per quale preciso motivo?
    Nel tuo codice gli errori sono per altri motivi: le eccezioni che hai definito sono "checked" (controllate, estendono Exception).

    Per il linguaggio Java è un ERRORE tentare di catturare una eccezione checked se il compilatore deduce che nel corpo del try quella eccezione checked NON viene lanciata mai. Perché il codice del catch sarebbe codice unreachable, non raggiungibile.

    E se all'interno di un metodo viene lanciata una eccezione checked, allora DEVE essere dichiarata con il throws nella dichiarazione del metodo.
    Ultima modifica di andbin; 19-08-2016 a 17:08
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2014
    Messaggi
    55
    Quote Originariamente inviata da andbin Visualizza il messaggio
    ..cut..
    ho capito, sei stato chiarissimo!
    quindi nel codice che ho postato nel primo post, gli errori stanno nel fatto che ci sono de catch che non vengono mai raggiunti mediante una istruzione throws nei blocchi try giusto?

    ho un'altra domanda: se c'è un lancio di eccezione nel blocco finally, il compilatore come si comporta? risale la call stack fino a trovare un catch compatibile con l'eccezione lanciata?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Lodin Visualizza il messaggio
    quindi nel codice che ho postato nel primo post, gli errori stanno nel fatto che ci sono de catch che non vengono mai raggiunti mediante una istruzione throws nei blocchi try giusto?
    Sì, come ripeto è in generale un errore cercare di catturare con catch una eccezione "checked" se il compilatore deduce che nel try quella eccezione NON viene mai lanciata (perché nulla la lancia esplicitamente nel try o nessun metodo invocato dal try la dichiara).

    Da questa regola sono esentate le eccezioni java.lang.Exception e java.lang.Throwable (che tecnicamente sono entrambe "checked") ma per un motivo molto semplice e logico. Queste eccezioni sono a monte sia delle eccezioni checked che unchecked. Pertanto deve essere possibile mettere un catch generico di Exception o Throwable anche in assenza di eccezioni checked, perché appunto ci possono essere anche solo eccezioni unchecked.

    Se invece tu estendi java.lang.Exception facendo una TuaException, questa è certamente solo checked, quindi vale di nuovo la regola detta sopra, ovvero se cerchi di fare catch (TuaException e) ma nel try nulla la lancia, è un errore.

    Quote Originariamente inviata da Lodin Visualizza il messaggio
    ho un'altra domanda: se c'è un lancio di eccezione nel blocco finally, il compilatore come si comporta? risale la call stack fino a trovare un catch compatibile con l'eccezione lanciata?
    Sì risale lungo lo stack all'indietro fino a trovare un catch applicabile.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.