[Eccezioni Java] Quale è la differenza tra lanciare un eccezione e dichiarare di poterla lanciare?

di il
5 risposte

[Eccezioni Java] Quale è la differenza tra lanciare un eccezione e dichiarare di poterla lanciare?

Salve, mi sto imbattendo per la prima volta sulle eccezioni in java.
Vorrei capire come da titolo, la differenza tra lanciare l'eccezione e dichiararla di poterla lanciare.
Nello specifico il testo che mi porta in confusione è il seguente:

Un metodo che invoca clone() può:

- gestire l’eccezione, cioè dire al compilatore cosa
fare
- non gestire l’eccezione, ma dichiarare di poterla
lanciare
-In tal caso, se l’eccezione viene lanciata, il
programma termina visualizzando un
messaggio di errore (a meno che non venga
gestita dal chiamante del metodo)

5 Risposte

  • Re: [Eccezioni Java] Quale è la differenza tra lanciare un eccezione e dichiarare di poterla lanciare?

    rairana ha scritto:


    Vorrei capire come da titolo, la differenza tra lanciare l'eccezione e dichiararla di poterla lanciare.
    Innanzitutto ti è chiara la differenza tra eccezioni "checked" e "unchecked"?
  • Re: [Eccezioni Java] Quale è la differenza tra lanciare un eccezione e dichiarare di poterla lanciare?

    andbin ha scritto:


    rairana ha scritto:


    Vorrei capire come da titolo, la differenza tra lanciare l'eccezione e dichiararla di poterla lanciare.
    Innanzitutto ti è chiara la differenza tra eccezioni "checked" e "unchecked"?
    Sisi la differenza mi è molto chiara.
  • Re: [Eccezioni Java] Quale è la differenza tra lanciare un eccezione e dichiarare di poterla lanciare?

    rairana ha scritto:


    Sisi la differenza mi è molto chiara.
    Bene. Allora sai che le eccezioni checked si dicono tali perché il compilatore "controlla" che siano sempre prese in considerazione in qualche modo dal programmatore, insomma non possono essere ignorate. Per le eccezioni unchecked non c'è alcun controllo o restrizione del genere.

    Per quelle checked, vale la regola "handle or declare", ovvero appunto o va catturata/gestita oppure va dichiarata nel metodo affinché possa uscire più fuori.

    Se ho un metodo:
    public void metodoA() {
        // ...
        metodoB();    // questo dichiara IOException
        // ...
    }
    NON posso lasciarlo così. metodoB() dichiara IOException che è "checked" (che poi la lanci veramente o no, è un altro discorso). Ma la dichiara e appunto non posso ignorarlo. Quindi ho 2 strade:

    a) catturarla e gestirla in qualche modo:
    public void metodoA() {
        // ...
        try {
            metodoB();    // questo dichiara IOException
        } catch (IOException e) {
            // ... una gestione ...
        }
        // ...
    }
    oppure

    b) dichiarare IOException (o supertipo) in metodoA
    public void metodoA() throws IOException {
        // ...
        metodoB();    // questo dichiara IOException
        // ...
    }
    In questo modo se metodoB lancia davvero IOException, questa può "uscire" da metodoA. Questo lo si fa generalmente quando in metodoA non c'è una conoscenza appropriata su come gestire l'eccezione e allora la cosa più semplice è delegare questo ad un livello superiore.

    Ma chi chiama metodoA ora si dovrà porre la STESSA questione: o cattura/gestisce l'eccezione oppure a sua volta la dichiara affinché esca ancora più a monte.
  • Re: [Eccezioni Java] Quale è la differenza tra lanciare un eccezione e dichiarare di poterla lanciare?

    andbin ha scritto:


    rairana ha scritto:


    Sisi la differenza mi è molto chiara.
    Bene. Allora sai che le eccezioni checked si dicono tali perché il compilatore "controlla" che siano sempre prese in considerazione in qualche modo dal programmatore, insomma non possono essere ignorate. Per le eccezioni unchecked non c'è alcun controllo o restrizione del genere.

    Per quelle checked, vale la regola "handle or declare", ovvero appunto o va catturata/gestita oppure va dichiarata nel metodo affinché possa uscire più fuori.

    Se ho un metodo:
    public void metodoA() {
        // ...
        metodoB();    // questo dichiara IOException
        // ...
    }
    NON posso lasciarlo così. metodoB() dichiara IOException che è "checked" (che poi la lanci veramente o no, è un altro discorso). Ma la dichiara e appunto non posso ignorarlo. Quindi ho 2 strade:

    a) catturarla e gestirla in qualche modo:
    public void metodoA() {
        // ...
        try {
            metodoB();    // questo dichiara IOException
        } catch (IOException e) {
            // ... una gestione ...
        }
        // ...
    }
    oppure

    b) dichiarare IOException (o supertipo) in metodoA
    public void metodoA() throws IOException {
        // ...
        metodoB();    // questo dichiara IOException
        // ...
    }
    In questo modo se metodoB lancia davvero IOException, questa può "uscire" da metodoA. Questo lo si fa generalmente quando in metodoA non c'è una conoscenza appropriata su come gestire l'eccezione e allora la cosa più semplice è delegare questo ad un livello superiore.

    Ma chi chiama metodoA ora si dovrà porre la STESSA questione: o cattura/gestisce l'eccezione oppure a sua volta la dichiara affinché esca ancora più a monte.
    Adesso mi è molto più chiaro, l'ultima cosa, da quello che ho capito l'ideale sarebbe gestire sempre le eccezioni ?
    Se non le gestiamo viene svolta invece l'azione di default, dico bene ?
  • Re: [Eccezioni Java] Quale è la differenza tra lanciare un eccezione e dichiarare di poterla lanciare?

    rairana ha scritto:


    da quello che ho capito l'ideale sarebbe gestire sempre le eccezioni ?
    No, l'ho detto prima: DIPENDE dal contesto e dalla conoscenza che si ha per poter gestire (o no) una eccezione.

    Un esempio banale: voglio fare un metodo es. readAllLines(File) che dato un java.io.File mi legge tutte le righe e le restituisce in un List<String>. Ora: in questo metodo andrò sicuramente ad usare classi e metodi di I/O che possono causare IOException. Che tipo di gestione potrei fare in readAllLines? Ben poco, al limite fare del "logging". Un metodo come readAllLines potrebbe essere usato in una applicazione console, o una grafica .. o ancora in una web application. Insomma, un readAllLines è abbastanza a basso livello e non "sa" nulla del contesto di utilizzo.
    La cosa più semplice e logica è lasciar uscire fuori l'eccezione (al massimo la si può catturare per logging e poi ri-lanciarla) dando la possibilità al chiamante di decidere cosa fare.

    rairana ha scritto:


    Se non le gestiamo viene svolta invece l'azione di default, dico bene ?
    Cosa intendi per "azione di default"?? L'unica cosa che c'è è che se una eccezione esce completamente a monte di un thread, per default viene stampato lo stacktrace della eccezione. Se impostassi tu un "uncaught exception handler" su un Thread, puoi fare una azione diversa da quella.
Devi accedere o registrarti per scrivere nel forum
5 risposte