Java Language Lanciare un'eccezione

Esempio

Il seguente esempio mostra le basi del lancio di un'eccezione:

public void checkNumber(int number) throws IllegalArgumentException {
    if (number < 0) {
        throw new IllegalArgumentException("Number must be positive: " + number);
    }
}

L'eccezione è lanciata sulla terza linea. Questa affermazione può essere suddivisa in due parti:

  • new IllegalArgumentException(...) sta creando un'istanza della classe IllegalArgumentException , con un messaggio che descrive l'errore segnalato da tale eccezione.

  • throw ... lancia quindi l'oggetto eccezione.

Quando viene generata l'eccezione, le istruzioni di chiusura vengono terminate in modo anomalo finché non viene gestita l'eccezione. Questo è descritto in altri esempi.

È buona norma creare e lanciare l'oggetto eccezione in una singola istruzione, come mostrato sopra. È inoltre buona norma includere un messaggio di errore significativo nell'eccezione per aiutare il programmatore a comprendere la causa del problema. Tuttavia, questo non è necessariamente il messaggio che dovresti mostrare all'utente finale. (Per cominciare, Java non ha supporto diretto per l'internazionalizzazione dei messaggi di eccezione.)

Ci sono un paio di altri punti da fare:

  • Abbiamo dichiarato il checkNumber come throws IllegalArgumentException . Questo non era strettamente necessario, poiché IllegalArgumentException è un'eccezione controllata; vedere La gerarchia delle eccezioni Java - Eccezioni non selezionate e controllate . Tuttavia, è buona pratica farlo e includere anche le eccezioni generate dai commenti javadoc di un metodo.

  • Codice immediatamente dopo che una dichiarazione di throw è irraggiungibile . Quindi se abbiamo scritto questo:

     throw new IllegalArgumentException("it is bad");
     return;
    

    il compilatore avrebbe segnalato un errore di compilazione per la dichiarazione di return .

Eccezione concatenata

Molte eccezioni standard hanno un costruttore con un secondo argomento di cause oltre all'argomento di message convenzionale. La cause consente di concatenare eccezioni. Ecco un esempio.

Per prima cosa definiamo un'eccezione non controllata che la nostra applicazione sta per gettare quando incontra un errore non recuperabile. Si noti che abbiamo incluso un costruttore che accetta un argomento di cause .

    public class AppErrorException extends RuntimeException {
        public AppErrorException() {
            super();
        }

        public AppErrorException(String message) {
            super(message);
        }

        public AppErrorException(String message, Throwable cause) {
            super(message, cause);
        }
    }

Successivamente, ecco un codice che illustra il concatenamento delle eccezioni.

    public String readFirstLine(String file) throws AppErrorException {
        try (Reader r = new BufferedReader(new FileReader(file))) {
            String line = r.readLine();
            if (line != null) {
                return line;
            } else {
                throw new AppErrorException("File is empty: " + file);
            }
        } catch (IOException ex) {
            throw new AppErrorException("Cannot read file: " + file, ex);
        }
    }

Il throw all'interno del blocco try rileva un problema e lo segnala tramite un'eccezione con un semplice messaggio. Al contrario, il throw all'interno del blocco catch sta gestendo IOException avvolgendolo in una nuova (controllata) eccezione. Tuttavia, non sta gettando via l'eccezione originale. Passando la IOException come cause , la registriamo in modo che possa essere stampata nello stacktrace, come spiegato in Creazione e lettura di stacktraces .