Comment définir la classe d'exception personnalisée en Java, la manière la plus simple?

286

J'essaie de définir ma propre classe d'exceptions de la manière la plus simple, et voici ce que j'obtiens:

public class MyException extends Exception {}

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

Voici ce que dit le compilateur Java:

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

J'avais le sentiment qu'il fallait hériter de ce constructeur java.lang.Exception, n'est-ce pas?

yegor256
la source

Réponses:

402

Non, vous n'héritez pas des constructeurs non par défaut, vous devez définir celui qui prend une chaîne dans votre classe. En règle générale, vous utilisez super(message)dans votre constructeur pour appeler votre constructeur parent. Par exemple, comme ceci:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}
djna
la source
58
@vulkanino: Non. Le constructeur par défaut est ajouté par le compilateur pour chaque classe qui ne définit pas de constructeur propre. Si vous définissez un constructeur explicite, vous n'obtenez pas la valeur par défaut même si la superclasse en a, et si votre classe n'a pas de constructeur, vous obtenez la valeur par défaut même si la superclasse ne l'a pas.
Michael Borgwardt
5
if your class has no constructor, you get the default even if the superclass does not have itLa dernière partie est impossible, sauf si la superclasse a un constructeur par défaut accessible à cette classe (peut être protégé ou protégé par package). Sinon, vous devez explicitement appeler l'un des constructeurs parents, sinon la compilation échouera.
Sean Patrick Floyd
43
Veuillez ajouter les constructeurs MyException(Throwable)et MyException(String, Throwable)pour prendre correctement en charge le chaînage des exceptions .
Danilo Piazzalunga
8
Près de 3 ans plus tard et aucun des constructeurs supplémentaires n'a été ajouté. :(
byxor
2
@BrandonIbbotson Qu'entendez-vous par «ils», et où sont-ils ajoutés? Si ce que vous entendez par «ils» sont des constructeurs de superclasses et par «où» est une sous-classe, alors vous vous trompez. Les constructeurs de superclasse ne sont pas implicitement ajoutés à la sous-classe. De plus, je ne vois aucun autre sujet dans les phrases précédentes pour que ces mots se réfèrent.
halil
90

Une exception personnalisée typique que je définirais est quelque chose comme ceci:

public class CustomException extends Exception {

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

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

}

Je crée même un modèle à l'aide d'Eclipse, je n'ai donc pas à réécrire toutes ces choses encore et encore.

nanda
la source
17
Vous pouvez simplement étendre Exception lors de la création de votre classe dans Eclipse et vous obtiendrez les quatre constructeurs. Vous n'avez pas besoin d'un modèle.
jeremyjjbrown
Quand devrions-nous utiliser le second Consutructor au lieu du premier?
ZhaoGang
61

Si vous utilisez la nouvelle boîte de dialogue de classe dans Eclipse, vous pouvez simplement définir le champ Superclasse sur java.lang.Exceptionet cocher "Constructeurs de la superclasse" et cela générera les éléments suivants:

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
    }

}

En réponse à la question ci-dessous à propos de ne pas appeler super()le constructeur defualt, Oracle a ceci à dire :

Remarque: Si un constructeur n'appelle pas explicitement un constructeur de superclasse, le compilateur Java insère automatiquement un appel au constructeur sans argument de la superclasse.

Kevin Brey
la source
22

La raison de ceci est expliquée dans l' article Héritage de la plate-forme Java qui dit:

"Une sous-classe hérite de tous les membres (champs, méthodes et classes imbriquées) de sa superclasse. Les constructeurs ne sont pas membres , ils ne sont donc pas hérités par les sous-classes, mais le constructeur de la superclasse peut être invoqué à partir de la sous-classe."

Isaq
la source
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());
        }
    }
}
Deepak Pakhale
la source
qu'est-ce que cela reviendrait?
user1876508
Il imprimerait simplement "Bonjour à nouveau avec exception personnalisée" qui provient du constructeur de UseCusomException, l'exception serait levée puis interceptée dans le principal qui afficherait "Ceci est mon exception personnalisée: Il s'agit d'une exception personnalisée".
ThePerson
2

La classe d'exception a deux constructeurs

  • public Exception() - Ceci construit une exception sans aucune information supplémentaire. La nature de l'exception est généralement déduite du nom de la classe.
  • public Exception(String s) - Construit une exception avec un message d'erreur spécifié. Un message détaillé est une chaîne qui décrit la condition d'erreur pour cette exception particulière.
Deepak Pakhale
la source
3
En fait, depuis Java 1.4, il existe deux autres constructeurs: public Exception(Throwable)et public Exception(String, Throwable). Ils sont nécessaires pour prendre correctement en charge le chaînage d'exceptions .
Danilo Piazzalunga
@DaniloPiazzalunga est d'accord avec vous. source: Résumé du constructeur docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU
0

Si vous héritez d'Exception, vous devez fournir un constructeur qui prend une chaîne en paramètre (il contiendra le message d'erreur).

vulkanino
la source
Je pense que vous devriez également ajouter la raison.
Jigar Joshi
3
en fait, c'est incorrect. Si votre code utilise un constructeur avec un argument String, vous devez le déclarer. Cependant, une sous-classe Exception peut être définie sans constructeur explicite ... car Exception a un constructeur sans argument.
Stephen C
0

et n'oubliez pas la façon la plus simple de lever une exception (vous n'avez pas besoin de créer une classe)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
Lorne K
la source