Come definire la classe di eccezione personalizzata in Java, il modo più semplice?


286

Sto cercando di definire la mia classe di eccezioni nel modo più semplice, e questo è quello che sto ottenendo:

public class MyException extends Exception {}

public class Foo {
  public bar() throws MyException {
    throw new MyException("try again please");
  }
}

Questo è ciò che dice il compilatore Java:

cannot find symbol: constructor MyException(java.lang.String)

Ho avuto la sensazione che questo costruttore debba essere ereditato java.lang.Exception, no?

Risposte:


402

No, non "erediti" i costruttori non predefiniti, devi definire quello che prende una stringa nella tua classe. In genere si utilizza super(message)nel costruttore per richiamare il costruttore principale. Ad esempio, in questo modo:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}

58
@vulkanino: No. Il costruttore predefinito viene aggiunto dal compilatore per ogni classe che non definisce alcun costruttore proprio. Se si definisce un costruttore esplicito, non si ottiene il valore predefinito anche se la superclasse ce l'ha, e se la propria classe non ha costruttore, si ottiene il valore predefinito anche se la superclasse non ce l'ha.
Michael Borgwardt,

5
if your class has no constructor, you get the default even if the superclass does not have itL'ultima parte è impossibile, a meno che la superclasse non abbia un costruttore predefinito accessibile a questa classe (può essere protetto o protetto da pacchetti). In caso contrario, è necessario chiamare esplicitamente uno dei costruttori principali, altrimenti la compilazione avrà esito negativo.
Sean Patrick Floyd,

43
Aggiungi i costruttori MyException(Throwable)e MyException(String, Throwable)per supportare correttamente il concatenamento delle eccezioni .
Danilo Piazzalunga,

8
Quasi 3 anni dopo e nessuno dei costruttori extra è stato aggiunto. :(
byxor,

2
@BrandonIbbotson Cosa intendi con "loro" e dove vengono aggiunti? Se ciò che intendevi per "loro" sono costruttori di superclassi e per "dove" è una sottoclasse, allora ti sbagli. I costruttori di superclasse non vengono aggiunti implicitamente alla sottoclasse. Inoltre non riesco a vedere nessun altro argomento nelle frasi precedenti a cui quelle parole possano fare riferimento.
halil

90

Una tipica eccezione personalizzata che definirei è qualcosa del genere:

public class CustomException extends Exception {

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

    public CustomException(String message, Throwable throwable) {
        super(message, throwable);
    }

}

Creo persino un modello usando Eclipse, quindi non devo scrivere più e più volte.


17
Puoi semplicemente estendere l'eccezione quando crei la tua classe in Eclipse e otterrai tutti e quattro i costruttori. Non hai bisogno di un modello.
jeremyjjbrown,

Quando dovremmo usare il secondo Consutructor invece del primo?
ZhaoGang

61

Se usi la finestra di dialogo della nuova classe in Eclipse puoi semplicemente impostare il campo Superclass su java.lang.Exceptione selezionare "Costruttori da superclasse" e genererà quanto segue:

package com.example.exception;

public class MyException extends Exception {

    public MyException() {
        // TODO Auto-generated constructor stub
    }

    public MyException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }

    public MyException(Throwable cause) {
        super(cause);
        // TODO Auto-generated constructor stub
    }

    public MyException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }

}

In risposta alla domanda qui sotto sul non chiamare super()il costruttore predefinito, Oracle ha questo da dire :

Nota: se un costruttore non invoca esplicitamente un costruttore di superclasse, il compilatore Java inserisce automaticamente una chiamata al costruttore senza argomento della superclasse.


1
Perché non è necessario che il costruttore predefinito chiami super()?
ceving


22

Il motivo è spiegato nell'articolo Ereditarietà della piattaforma Java che dice:

"Una sottoclasse eredita tutti i membri (campi, metodi e classi nidificate) dalla sua superclasse. I costruttori non sono membri , quindi non sono ereditati da sottoclassi, ma il costruttore della superclasse può essere richiamato dalla sottoclasse."


19
package customExceptions;

public class MyException extends Exception{

    public MyException(String exc)
    {
        super(exc);
    }
    public String getMessage()
    {
        return super.getMessage();
    }
}

import customExceptions.MyException;

public class UseCustomException {

    MyException newExc=new MyException("This is a custom exception");

    public UseCustomException() throws MyException
    {
        System.out.println("Hello Back Again with custom exception");
        throw newExc;       
}

    public static void main(String args[])
    {
        try
        {
            UseCustomException use=new UseCustomException();
        }
        catch(MyException myEx)
        {
            System.out.println("This is my custom exception:" + myEx.getMessage());
        }
    }
}

cosa sarebbe questo ritorno?
user1876508,

Sarebbe semplicemente stampare "Hello Back Again con eccezione personalizzata" che proviene dal costruttore di UseCusomException, l'eccezione verrebbe generata e catturata nel principale che stamperebbe "Questa è la mia eccezione personalizzata: questa è un'eccezione personalizzata".
ThePerson,

2

La classe di eccezione ha due costruttori

  • public Exception() - Costruisce un'eccezione senza ulteriori informazioni. La natura dell'eccezione viene generalmente dedotta dal nome della classe.
  • public Exception(String s) - Crea un'eccezione con un messaggio di errore specificato. Un messaggio di dettaglio è una stringa che descrive la condizione di errore per questa particolare eccezione.

3
In realtà, a partire da Java 1.4, ci sono altri due costruttori: public Exception(Throwable)e public Exception(String, Throwable). Sono necessari per supportare correttamente il concatenamento delle eccezioni .
Danilo Piazzalunga,

@DaniloPiazzalunga sono d'accordo con te. fonte: Riepilogo costruttore docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU

0

Se si eredita da Exception, è necessario fornire un costruttore che accetta una stringa come parametro (conterrà il messaggio di errore).


Penso che dovresti aggiungere anche la ragione.
Jigar Joshi,

3
in realtà, non è corretto. Se il tuo codice utilizza un costruttore con un argomento String, devi dichiararlo. Tuttavia, una sottoclasse di eccezione può essere definita senza costruttori espliciti ... poiché Exception ha un costruttore no-args.
Stephen C,

0

e non dimenticare il modo più semplice per generare un'eccezione (non è necessario creare una classe)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.