Quote Originariamente inviata da newutente Visualizza il messaggio
Quindi se parliamo di eccezioni unchecked (tutte le sottoclassi di RuntimeException) è sufficiente utilizzare throw quindi lanciando l'eccezione ma senza preoccuparsi di catturarla tramite il try-catch.
Non c'entra nulla.
Le eccezioni unchecked sono eccezioni che il programmatore non è costretto a gestire. Né con try/catch, né con throws. Sono tipi particolari di eccezione che possono essere sollevati a scopo "informativo" per il programmatore dell'applicazione. Se vengono sollevate, il più delle volte significa che il programma non è stato fatto nel modo corretto. Un paio di esempi per chiarire:

- IndexOutOfBoundsException. Se viene sollevata, significa che si è cercato di sforare l'indice di un array: questo, il più delle volte, non significa che il programmatore debba gestire questa eccezione; significa, piuttosto, che il programmatore, prima di fare sciocchezze, dovrebbe controllare la lunghezza dell'array e evitare di sforarlo.

- ArithmeticException. Se viene sollevata significa che il programma sta facendo dei calcoli che non può fare. L'esempio classico è la divisione per 0: il programmatore deve evitare di far fare al programma divisioni per zero, non fargliele fare ed, eventualmente, gestire l'eccezione.


Quello che non mi è chiaro però è se c'è differenza tra lanciare una eccezione e gestirla altrove oppure lanciarla e gestirla nel metodo stesso.
Cioè, se questi due frammenti di codice sono equivalenti:
codice:
public class Esempio
{
...
    public void aggiungi()
    {
        try
        {
                ...    
            throw new EccezioneException();
        }
        catch (EccezioneException exc)
        {
            ...
        }
    }
...
}
codice:
public class Principale
{
    public static void main(String args[])
    {
        Esempio esempio = new Esempio();
        
        try
        {
            esempio.aggiungi();
        }
        catch (EccezioniException exc)
        {
            ...
        }
    }
}



public class Esempio
{
...
    public void aggiungi() throws EccezioneException
    {
        ...    
        throw new EccezioneException();        
    }
...
}
Da nessuna parte (se non nei libri e, comunque, nel materiale didattico) troverai mai del codice come il primo. Semplicemente perchè non ha alcun senso (dal punto di vista pratico e logico). Ben diverso è il caso del secondo esempio. Lì c'è un metodo che può essere potenzialmente richiamato da più parti del codice (addirittura da codice esterno). Quel metodo sta dicendo: io faccio il mio lavoro, ma se succede qualcosa di anomalo, lo segnalo ma non mi preoccupo di gestirlo. E i motivi per una scelta di questo tipo sono molteplici:

1) Io, metodo, non sono in grado di gestire quel caso particolare
2) Io, metodo, non mi voglio sporcare le mani: non ho una visione sufficientemente ampia del contesto in cui sono stato chiamato, quindi è meglio che sia il chiamante a gestire la cosa (che ha una visione più ampia)
3) Io, metodo, potrei anche gestire l'eccezione, ma forse è meglio non lo faccia perchè il chiamante potrebbe essere interessato a sapere se qualcosa è andato storto.
4) Io, metodo, gestisco solo una parte delle eccezioni che possono insorgere durante il lavoro, ma il resto lo lascio gestire a chi mi chiama (i casi più gravi)
5) Io, metodo, gestisco l'eccezione, ma la rilancio al chiamante con delle informazioni in più, che possono tornargli utili per decidere come gestire il caso.

Se un metodo ha tutte le informazioni per poter gestire un'eccezione, può farlo e non dire nulla a nessuno. Userà un try/catch e finita lì. Altrimenti, se sussistono uno o più dei motivi sopra elencati (non è un elenco esaustivo), semplicemente agirà di conseguenza.


Ciao.