t
t
t
t
t t 10) Gestion des erreurs avec les exceptions
tttt
10) Gestion des erreurs avec les exceptions
Texte original t Traducteur : N. CULWELL-KANAREK, Anthony PRAUD, A. FORTUN
t
t
    
Ce chapitre contient 3 pages
1 2 3
\\\
t t t
t t t
t
2004.02.05 - version 0.3 :
- Fin de la correction du chapitre. Refait la partie traduite par papashultz, trop mauvaise (genre logiciel de traduction automatique).
- Repassage au correcteur d'orth d'openoffice.
2003.06.24 - Version 0.2 :
- Mise en forme du code html (titres-hx[verdana], paragraphes-p[Georgia], code-blockquote);
- Premier passage rapide au correcteur Orth (Starffice5.2).
2003.04.18 - Version 0.1 :
- Première version, traduction non terminée.
Traducteur :
- Anthony PRAUD
Texte original :
-Thinking in Java, 2nd edition, Revision 10
© 2000 by Bruce Eckel
t t t
10: Error Handling with Exceptions t Gestion des erreurs avec les exceptions
t t t
The basic philosophy of Java is that “badly formed code will not be run.” t La philosophie de base de Java est que « un code mal formé ne sera pas exécuté ».
t t t
The ideal time to catch an error is at compile-time, before you even try to run the program. However, not all errors can be detected at compile-time. The rest of the problems must be handled at run-time, through some formality that allows the originator of the error to pass appropriate information to a recipient who will know how to handle the difficulty properly. t L'instant idéal pour détecter une erreur est la compilation, bien avant que vous essayiez d'exécuter le programme. Malheureusement, toutes les erreurs ne peuvent être détectées à cette étape. Les problèmes restants doivent être gérés à l'exécution avec un certain formalisme qui permet à l'initiateur de l'erreur de passer une information suffisante à un récepteur qui va savoir comment traiter proprement cette anomalie.
t t t
In C and other earlier languages, there could be several of these formalities, and they were generally established by convention and not as part of the programming language. Typically, you returned a special value or set a flag, and the recipient was supposed to look at the value or the flag and determine that something was amiss. However, as the years passed, it was discovered that programmers who use a library tend to think of themselves as invincible—as in, “Yes, errors might happen to others, but not in my code.” So, not too surprisingly, they wouldn’t check for the error conditions (and sometimes the error conditions were too silly to check for[51]). If you were thorough enough to check for an error every time you called a method, your code could turn into an unreadable nightmare. Because programmers could still coax systems out of these languages they were resistant to admitting the truth: This approach to handling errors was a major limitation to creating large, robust, maintainable programs. t En C et dans d'autres langages plus anciens, il pouvait y avoir plusieurs formalismes, et ils étaient généralement établis comme des conventions et pas comme partie intégrante du langage de programmation. la gestion des erreurs se faisant typiquement en retournant par exemple une valeur spécifique ou en positionnant un drapeau [flag], le récepteur avait la charge de tester ces données et de déterminer qu'il y avait eu une anomalie. Malgré cela au fil des ans on se rendit compte que les programmeurs qui utilisent des librairies avaient tendance à se croire infaillible « oui des erreurs peuvent se produire chez les autres mais pas dans mon code ! » Alors, de façon quasi naturelle, ils ne souhaitaient pas tester les conditions d'erreur (elles étaient parfois trop grossières pour être testées [51]. Si vous étiez assez méticuleux pour tester toutes les conditions d'erreur à chaque appel de fonction votre code pouvait devenir d'une illisibilité cauchemardesque. Parce que les programmeurs avaient toujours la possibilité de coupler un système avec ces langages ils étaient réticents à admettre la vérité : cette approche de la gestion des erreurs était un obstacle à la création de grands programmes, robustes et faciles à maintenir.
t t t
The solution is to take the casual nature out of error handling and to enforce formality. This actually has a long history, since implementations of exception handling go back to operating systems in the 1960s, and even to BASIC’s “on error goto.” But C++ exception handling was based on Ada, and Java’s is based primarily on C++ (although it looks even more like Object Pascal). t La solution est prendre la nature primitive de la gestion des erreurs et de renforcer le formalisme. Cette solution à une longue histoire, puisque l'implémentation de la gestion des erreurs remonte au systèmes d'exploitation des années soixante et même au « ON ERROR GOTO » du BASIC. Mais la gestion des erreurs du C++ était basée sur ADA, et Java est basé sur le C++ (bien qu'il ressemble plus a du pascal objet).
t t t
The word “exception” is meant in the sense of “I take exception to that.” At the point where the problem occurs you might not know what to do with it, but you do know that you can’t just continue on merrily; you must stop and somebody, somewhere, must figure out what to do. But you don’t have enough information in the current context to fix the problem. So you hand the problem out to a higher context where someone is qualified to make the proper decision (much like a chain of command). t Le « Mot » exception est pris dans le sens « je fais exception de ce cas ». A l'instant ou le problème se produit vous pouvez ne pas savoir quoi en faire mais vous savez que vous ne pouvez pas continuer sans vous en soucier ; vous devez vous arrêter et quelqu'un quelque part doit savoir que faire. Donc vous transmettez le problème dans un contexte plus général ou quelqu'un est qualifié pour prendre la décision appropriée (comme dans une chaîne de commandement).
t t t
The other rather significant benefit of exceptions is that they clean up error handling code. Instead of checking for a particular error and dealing with it at multiple places in your program, you no longer need to check at the point of the method call (since the exception will guarantee that someone catches it). And, you need to handle the problem in only one place, the so-called exception handler. This saves you code, and it separates the code that describes what you want to do from the code that is executed when things go awry. In general, reading, writing, and debugging code becomes much clearer with exceptions than when using the old way of error handling. t l'autre apport significatif de la gestion des exceptions est qu'elle simplifie le code de la gestion des erreurs. Au lieu de tester une condition d'erreur et la traiter à différents endroits de votre programme, vous n'avez plus besoin de placer le code de gestion des erreurs à l'appel de la méthode (puisque l'exception garantira que quelqu'un la lèvera) et vous avez juste besoin de traiter le problème à un seul endroit, appelé Exception Handler. Cette gestion vous permet d'économiser du code, et de séparer le code que vous voulez exécuter du code qui doit être exécuté quand des erreurs se produisent. Généralement, la lecture l'écriture et le déboguage du code est plus claire avec les exceptions qu'avec l'ancienne méthode.
t t t
Because exception handling is enforced by the Java compiler, there are only so many examples that can be written in this book without learning about exception handling. This chapter introduces you to the code you need to write to properly handle exceptions, and the way you can generate your own exceptions if one of your methods gets into trouble. t La gestion des exceptions étant supportée par le Compilateur JAVA, il y a de nombreux exemples qui peuvent être écrits dans ce livre sans apprendre le mécanisme de gestion des exceptions. Ce chapitre vous instruit sur le code dont vous avez besoin pour gérer de façon adéquate les exceptions, et la façon de générer vos propres exceptions si une de vos méthodes venait à ne pas fonctionner.
t t t

Basic exceptions

t

Les exceptions de base

t t t
An exceptional condition is a problem that prevents the continuation of the method or scope that you’re in. It’s important to distinguish an exceptional condition from a normal problem, in which you have enough information in the current context to somehow cope with the difficulty. With an exceptional condition, you cannot continue processing because you don’t have the information necessary to deal with the problem in the current context. All you can do is jump out of the current context and relegate that problem to a higher context. This is what happens when you throw an exception. t Une condition exceptionnelle est un problème qui interdit de continuer la méthode ou la partie de code que vous êtes en train d'exécuter. il est important de distinguer une condition exceptionnelle d'un problème normal. Avec une condition exceptionnelle vous ne pouvez pas continuer l'exécution car vous n'avez pas suffisamment d'informations pour la traiter dans le contexte courant. Tout ce que vous pouvez faire est de changer de contexte et d'essayer de régler ce problème dans un contexte de plus haut niveau. C'est ce qui se passe quand vous générez une exception.
t t t
A simple example is a divide. If you’re about to divide by zero, it’s worth checking to make sure you don’t go ahead and perform the divide. But what does it mean that the denominator is zero? Maybe you know, in the context of the problem you’re trying to solve in that particular method, how to deal with a zero denominator. But if it’s an unexpected value, you can’t deal with it and so must throw an exception rather than continuing along that path. t Un exemple simple est la division. Si vous vous apprêtez à diviser par Zéro, il est intéressant de vérifier que le dénominateur est non nul avant d'effectuer la division. Mais qu'est ce que cela signifie que le dénominateur soit égal à zéro ? Peut être savez vous, dans le contexte, de cette méthode particulière comment agir avec un dénominateur égal à Zéro. Mais si c'est une valeur inattendue, vous ne pouvez pas la traiter et vous devez donc générer une exception plutôt que de continuer l'exécution.
t t t
When you throw an exception, several things happen. First, the exception object is created in the same way that any Java object is created: on the heap, with new. Then the current path of execution (the one you couldn’t continue) is stopped and the reference for the exception object is ejected from the current context. At this point the exception handling mechanism takes over and begins to look for an appropriate place to continue executing the program. This appropriate place is the exception handler, whose job is to recover from the problem so the program can either try another tack or just continue. t Quand vous générez une exception, plusieurs actions sont déclenchées. Premièrement, l'objet Exception est instancié de la même façon que tout objet java est crée : à la volée avec l'instruction new. Ensuite le chemin courant d'exécution (celui que vous ne pouvez continuer) est stoppé et la référence à l'objet exception est sortie du contexte courant. A cet instant le mécanisme des gestion des exceptions prend la main et commence à chercher un endroit approprié pour continuer à exécuter le programme. Cet endroit est le Gestionnaire d'exception (Exception Handler), dont la tâche est de résoudre le problème de façon à ce que le programme puisse essayer de lancer ou une autre tâche ou juste continuer en séquence.
t t t
As a simple example of throwing an exception, consider an object reference called t. It’s possible that you might be passed a reference that hasn’t been initialized, so you might want to check before trying to call a method using that object reference. You can send information about the error into a larger context by creating an object representing your information and “throwing” it out of your current context. This is called throwing an exception. Here’s what it looks like: t Pour prendre un exemple simple, considérons une instance d'objet appelée t. Il est possible qu'il vous soit passé une référence qui n'ai pas été initialisée, donc vous pouvez vouloir vérifier son initialisation avant d'appeler une méthode sur cette instance. Vous pouvez envoyer l'information sur l'erreur dans un contexte plus général en créant un objet représentant votre information et en la lançant depuis votre contexte. Cette action s'appelle générer une exception. Cette action ressemble à ceci :
t t t
if(t == null)
throw new NullPointerException();
t
if(t == "#0000FF">null)
  throw "#0000FF">new NullPointerException();
t t t
This throws the exception, which allows you—in the current context—to abdicate responsibility for thinking about the issue further. It’s just magically handled somewhere else. Precisely where will be shown shortly. t Ce code génère l'exception ,ce qui vous permet de vous décharger de la responsabilité de penser à ce problème pour le moment. C'est juste par magie traité autre part. Nous verrons, succinctement, cela se passe.
t t t

Exception arguments

t

Les paramètres des Exceptions

t t t
Like any object in Java, you always create exceptions on the heap using new, which allocates storage and calls a constructor. There are two constructors in all standard exceptions: the first is the default constructor, and the second takes a string argument so you can place pertinent information in the exception: t Comme pour tout objet en Java, vous créez des exceptions dans la pile [Heap] en utilisant new, qui alloue de l'espace mémoire et appelle un constructeur. Il y a deux constructeurs dans toutes les exceptions standards : le premier est le constructeur par défaut et le second prend une chaîne de caractères comme argument ainsi vous pouvez placer des informations pertinentes dans l'exception :
t t t
if(t == null)
throw new NullPointerException("t = null");
t
if(t == "#0000FF">null)
  throw "#0000FF">new NullPointerException("#004488">"t = null");
t t t
This string can later be extracted using various methods, as will be shown shortly. t Cette chaîne de caractères peut être extraite ultérieurement de différentes façons, nous verrons cela brièvement.
t t t
The keyword throw causes a number of relatively magical things to happen. Typically, you’ll first use new to create an object that represents the error condition. You give the resulting reference to throw. The object is, in effect, “returned” from the method, even though that object type isn’t normally what the method is designed to return. A simplistic way to think about exception handling is as an alternate return mechanism, although you get into trouble if you take that analogy too far. You can also exit from ordinary scopes by throwing an exception. But a value is returned, and the method or scope exits. t Le mot-clé throw déclenche une série d'événements relativement magiques. Typiquement, vous allez d'abord utilisez new pour instancier un objet qui représente la condition d'erreur. Vous transmettez la référence résultante au throw. L'objet est en effet retourné par la méthode, même si ce n'est pas ce type d'objet que la méthode doit renvoyer. Une vision simpliste de la gestion des exceptions est de la considérer comme un mécanisme de retour mais vous allez au devant de problèmes si vous poursuivez cette analogie trop loin. Vous pouvez aussi sortir de l'exécution normale en lançant une exception. Mais une valeur est retournée et la méthode ou l'environnement se termine.
t t t
Any similarity to an ordinary return from a method ends here, because where you return is someplace completely different from where you return for a normal method call. (You end up in an appropriate exception handler that might be miles away—many levels lower on the call stack—from where the exception was thrown.) t Toute similitude avec un retour ordinaire d'une méthode s'arrête ici parce que l'endroit vous arrivez est complètement différent de celui d'un retour normal d'une méthode. (Vous atterrissez chez le gestionnaire d'exception approprié qui peut être très éloigné, plusieurs niveau plus bas sur la pile d'appels, de l'endroit ou l'exception a été générée.)
t t t
In addition, you can throw any type of Throwable object that you want. Typically, you’ll throw a different class of exception for each different type of error. The information about the error is represented both inside the exception object and implicitly in the type of exception object chosen, so someone in the bigger context can figure out what to do with your exception. (Often, the only information is the type of exception object, and nothing meaningful is stored within the exception object.) t De plus, vous pouvez lancer n'importe quel type d'objet Throwable. Ainsi vous générerez une classe d'exception pour chaque type d'erreur. l'information à propos de l'erreur est contenue à la fois dans l'objet exception et implicitement dans le type de l'objet exception choisi, afin que quelqu'un dans le contexte supérieur sache quoi faire de votre exception (Souvent, la seule information est le type de l'objet exception rien d'autre de significatif est stocké.)
t t t

Catching an exception

t

Attraper une exception

t t t
If a method throws an exception, it must assume that exception is “caught” and dealt with. One of the advantages of Java exception handling is that it allows you to concentrate on the problem you’re trying to solve in one place, and then deal with the errors from that code in another place. t Si une méthode génère une exception elle doit supposer qu'elle sera intercepté et levée. Un des avantages de la gestion des exceptions dans Java est qu'elle vous permet de vous concentrer sur le problème que vous essayez de résoudre à un endroit, et enfin de placer le code concernant les erreurs à un autre endroit.
t t t
To see how an exception is caught, you must first understand the concept of a guarded region, which is a section of code that might produce exceptions, and which is followed by the code to handle those exceptions. t Pour comprendre comment une exception est levée vous devez comprendre le concept de région surveillée qui est une région de code qui peut générer des exceptions et qui est suivie par le code qui traite ces exceptions.
t t t

The try block

t

Le bloc try

t t t
If you’re inside a method and you throw an exception (or another method you call within this method throws an exception), that method will exit in the process of throwing. If you don’t want a throw to exit the method, you can set up a special block within that method to capture the exception. This is called the try block because you “try” your various method calls there. The try block is an ordinary scope, preceded by the keyword try: t Si vous êtes à l'intérieur d'une méthode et que vous générez une exception (ou une méthode à l'intérieur de celle ci génère une exception), cette méthode va sortir dans le processus de génération de l'exception. Si vous ne voulez pas qu'un throw provoque la sortie de la méthode vous pouvez spécifier un bloc spécial à l'intérieur de celle-ci qui va intercepter l'exception. C'est le Bloc try appelé ainsi car vous essayez vos différents appels de méthode ici . Le bloc try est une section ordinaire précédé du mot clé try.
t t t
try {
  // Code that might generate exceptions
}
t
try {
  // Code that might generate exceptions
}
t t t
If you were checking for errors carefully in a programming language that didn’t support exception handling, you’d have to surround every method call with setup and error testing code, even if you call the same method several times. With exception handling, you put everything in a try block and capture all the exceptions in one place. This means your code is a lot easier to write and easier to read because the goal of the code is not confused with the error checking. t Si vous vouliez tester les erreurs attentivement dans un langage de programmation qui ne supporte pas la gestion des exceptions vous devriez entourez l'appel de chaque méthode avec le code de vérification de l'initialisation et de vérification des erreurs, même si vous appeliez la même méthode plusieurs fois. Avec la Gestion des exceptions vous mettez tout dans le bloc try et capturer toute les exceptions en un seul endroit. Cela signifie que votre code est beaucoup plus simple à lire et à écrire car le bon code est séparé de celui de la gestion des erreurs.
t t t

Exception handlers

t

Les gestionnaires d'exceptions

t t t
Of course, the thrown exception must end up someplace. This “place” is the exception handler, and there’s one for every exception type you want to catch. Exception handlers immediately follow the try block and are denoted by the keyword catch: t Bien sûr, l'exception générée doit être traitée quelque part. Cet endroit est le gestionnaire d'exceptions, et il y en a un pour chaque type d'exception que vous voulez intercepter. Les gestionnaires d'exceptions sont placés juste derrière le bloc try. Et reconnaissables par le mot clé catch.
t t t
try {
  // Code that might generate exceptions
} catch(Type1 id1) {
  // Handle exceptions of Type1
} catch(Type2 id2) {
  // Handle exceptions of Type2
} catch(Type3 id3) {
  // Handle exceptions of Type3
}

// etc...
t
try {
  // Code that might generate exceptions
} catch(Type1 id1) {
  // Handle exceptions of Type1
} catch(Type2 id2) {
  // Handle exceptions of Type2
} catch(Type3 id3) {
  // Handle exceptions of Type3
}
// etc...
t t t
Each catch clause (exception handler) is like a little method that takes one and only one argument of a particular type. The identifier (id1, id2, and so on) can be used inside the handler, just like a method argument. Sometimes you never use the identifier because the type of the exception gives you enough information to deal with the exception, but the identifier must still be there. t Chaque clause du catch (gestionnaire d'exception) est comme une méthode qui ne prend qu'un argument d'un type particulier. Les identifiants (id1,id2, et ainsi de suite) peuvent êtres utilisés dans les gestionnaire d'exception, comme des paramètres de méthodes. Quelque fois vous n'utilisez pas l'identifiant car le type de l'exception vous fournit assez d'informations pour la traiter mais il doit toujours être présent.
t t t
The handlers must appear directly after the try block. If an exception is thrown, the exception handling mechanism goes hunting for the first handler with an argument that matches the type of the exception. Then it enters that catch clause, and the exception is considered handled. The search for handlers stops once the catch clause is finished. Only the matching catch clause executes; it’s not like a switch statement in which you need a break after each case to prevent the remaining ones from executing. t Le gestionnaire doit être placé juste derrière le bloc try. Si une exception est générée, le mécanisme de gestion des exceptions va à la recherche du premier gestionnaire d .exception dont le type correspond à celui de l'exception, cette recherche se termine quand une des clauses Catch est exécutée. Seulement une clause catch sera exécutée ; ce n'est pas comme un switch ou vous devez positionner un break après chaque case pour empêcher les autres conditions de s'exécuter.
t t t
Note that, within the try block, a number of different method calls might generate the same exception, but you need only one handler. t Prenez note qu'avec le bloc try, différentes méthodes peuvent générer la même exception mais vous n'aurez besoin que d'un seul gestionnaire d'exception.
t t t

Termination vs. resumption

t

Terminaison contre Restauration

t t t
There are two basic models in exception handling theory. In termination (which is what Java and C++ support), you assume the error is so critical that there’s no way to get back to where the exception occurred. Whoever threw the exception decided that there was no way to salvage the situation, and they don’t want to come back. t Ce sont les deux modèles de base dans la théorie de la gestion des exceptions. Dans la terminaison (supportée par Java et C++) on suppose que l'erreur est si critique qu'il n'est pas possible de recommencer l'exécution à partir de l'endroit ou c'est produit l'exception. Celui qui génère l'exception décide qu'il n'y a pas de solution pour restaurer la situation et ne veut pas revenir en arrière.
t t t
The alternative is called resumption. It means that the exception handler is expected to do something to rectify the situation, and then the faulting method is retried, presuming success the second time. If you want resumption, it means you still hope to continue execution after the exception is handled. In this case, your exception is more like a method call—which is how you should set up situations in Java in which you want resumption-like behavior. (That is, don’t throw an exception; call a method that fixes the problem.) Alternatively, place your try block inside a while loop that keeps reentering the try block until the result is satisfactory. t L'autre solution est appelée restauration. Cela signifie que le gestionnaire d'exception est censé agir pour corriger la situation, et ainsi la méthode incriminée est de nouveau exécutée avec un succès présumé. Si vous voulez utilisez la restauration, cela signifie que vous voulez que l'exécution continue après le traitement de l'exception. Dans cette optique votre exception est résolue par un appel de méthode qui est la façon dont vous devriez résoudre vos problèmes en Java si vous voulez avoir un comportement de Type restauration dans la gestion de vos exceptions. autrement placez votre bloc try dans un bloc while qui continuera a exécuter le bloc try tant que le résultat ne sera pas satisfaisant.
t t t
Historically, programmers using operating systems that supported resumptive exception handling eventually ended up using termination-like code and skipping resumption. So although resumption sounds attractive at first, it isn’t quite so useful in practice. The dominant reason is probably the coupling that results: your handler must often be aware of where the exception is thrown from and contain nongeneric code specific to the throwing location. This makes the code difficult to write and maintain, especially for large systems where the exception can be generated from many points. t Historiquement, les programmeur utilisant des systèmes d'exploitation qui supportaient la gestion des exceptions restauratrice finissaient par utiliser un code qui ressemblait à celui de la terminaison laissant de côté la restauration. Bien que la restauration ait l'air attractive au départ elle n'est pas aisée à mettre en oeuvre. La raison dominante est le couplage que cela générait : votre gestionnaire d'exception doit être conscient de l'endroit ou est générée l'exception et contenir du code générique indépendant de la localisation de sa génération. Cela rend le code difficile à écrire et à maintenir, surtout dans le cadre de grands systèmes où les exceptions peuvent surgir de nulle part.
t t t

Creating your own exceptions

t

Créez vos propres Exceptions

t t t
You’re not stuck using the existing Java exceptions. This is important because you’ll often need to create your own exceptions to denote a special error that your library is capable of creating, but which was not foreseen when the Java exception hierarchy was created. t Vous n'êtes pas obligés de vous cantonner aux exceptions Java. Ceci est important car vous aurez souvent besoin de créez vos exceptions pour distinguer une erreur que votre librairie est capable de générer, mais qui n'a pas été prévue lorsque la hiérarchie des exceptions Java a été pensée.
t t t
To create your own exception class, you’re forced to inherit from an existing type of exception, preferably one that is close in meaning to your new exception (this is often not possible, however). The most trivial way to create a new type of exception is just to let the compiler create the default constructor for you, so it requires almost no code at all: t Pour créer votre propre classe d'exception, vous devez hériter d'un type d'exception déjà existant, de préférence une qui est proche de votre nouvelle exception ( parfois ce n'est pas possible). La façon la plus simple de créer une exception est de laisser le compilateur créer le constructeur par défaut, ainsi vous n'avez pas besoin d'écrire de code.
t t t
//: c10:SimpleExceptionDemo.java
// Inheriting your own exceptions.
class SimpleException extends Exception {}

public class SimpleExceptionDemo {
  public void f() throws SimpleException {
    System.out.println(
      "Throwing SimpleException from f()");
    throw new SimpleException ();
  }
  public static void main(String[] args) {
    SimpleExceptionDemo sed =
      new SimpleExceptionDemo();
    try {
      sed.f();
    } catch(SimpleException e) {
      System.err.println("Caught it!");
    }
  }
} ///:~
t
"#009900">//: c10:SimpleExceptionDemo.java
// Inheriting your own exceptions.
class SimpleException "#0000FF">extends Exception {}
public "#0000FF">class SimpleExceptionDemo {
  public "#0000FF">void f() "#0000FF">throws SimpleException {
    System.out.println(
      "Throwing SimpleException from f()");
    throw "#0000FF">new SimpleException ();
  }
  public "#0000FF">static "#0000FF">void main(String[] args) {
    SimpleExceptionDemo sed =
      new SimpleExceptionDemo();
    try {
      sed.f();
    } catch(SimpleException e) {
      System.err.println("Caught it!");
    }
  }
} ///:~
t t t
When the compiler creates the default constructor, it which automatically (and invisibly) calls the base-class default constructor. Of course, in this case you don’t get a SimpleException(String) constructor, but in practice that isn’t used much. As you’ll see, the most important thing about an exception is the class name, so most of the time an exception like the one shown above is satisfactory. t Quand le compilateur crée le constructeur par défaut, celui ci automatiquement appelle le constructeur de base par défaut de la classe. Bien sûr vous n'obtenez pas un constructeur SimpleException(String) par défaut mais ce constructeur n'est guère utilisé. Comme vous le constaterez la chose la plus importante à propos d'une exception est le nom de sa classe, donc la plupart du temps une exception comme celle décrite au dessus est satisfaisante.
t t t
Here, the result is printed to the console standard error stream by writing to System.err. This is usually a better place to send error information than System.out, which may be redirected. If you send output to System.err it will not be redirected along with System.out so the user is more likely to notice it. t Ici le résultat est envoyé vers le flux d'.erreur standard de la console en écrivant dans System.err. C'est habituellement un meilleur endroit pour diriger les informations sur les erreurs que System.Out, qui peut être re-dirigé. Si vous envoyez le flux de sortie vers System.err il ne sera pas re-dirigé de la même façon que System.out donc l'utilisateur pourra le remarquer plus aisément.
t t t
Creating an exception class that also has a constructor that takes a String is also quite simple: t Créer une classe d'exception dont le constructeur a aussi un constructeur qui prend un argument de type string est assez simple :
t t t
//: c10:FullConstructors.java
// Inheriting your own exceptions.

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

public class FullConstructors {
  public static void f() throws MyException {
    System.out.println(
      "Throwing MyException from f()");
    throw new MyException();
  }
  public static void g() throws MyException {
    System.out.println(
      "Throwing MyException from g()");
    throw new MyException("Originated in g()");
  }
  public static void main(String[] args) {
    try {
      f();
    } catch(MyException e) {
      e.printStackTrace(System.err);
    }
    try {
      g();
    } catch(MyException e) {
      e.printStackTrace(System.err);
    }
  }
} ///:~
t
//: c10:FullConstructors.java
// Inheriting your own exceptions.
class MyException "#0000FF">extends Exception {
  public MyException() {}
  public MyException(String msg) {
    super(msg);
  }
}
public "#0000FF">class FullConstructors {
  public "#0000FF">static void f() "#0000FF">throws MyException {
    System.out.println(
      "Throwing MyException from f()");
    throw "#0000FF">new MyException();
  }
  public "#0000FF">static void g() "#0000FF">throws MyException {
    System.out.println(
      "Throwing MyException from g()");
    throw "#0000FF">new MyException("#004488">"Originated in g()");
  }
  public "#0000FF">static "#0000FF">void main(String[] args) {
    try {
      f();
    } catch(MyException e) {
      e.printStackTrace(System.err);
    }
    try {
      g();
    } catch(MyException e) {
      e.printStackTrace(System.err);
    }
  }
} ///:~
t t t
The added code is small—the addition of two constructors that define the way MyException is created. In the second constructor, the base-class constructor with a String argument is explicitly invoked by using the super keyword. t Le code ajouté est minime, deux constructeurs qui définissent la façon dont MyException est crée. Dans le second constructeur, le constructeur de base avec un argument de type String est appelé de façon explicité avec le mot clé super.
t t t
The stack trace information is sent to System.err so that it’s more likely it will be noticed in the event that System.out has been redirected. t L'information de la pile des appels est redirigée vers System.err ainsi on notera plus simplement dans l'événement que system.out a été redirigé.
t t t
The output of the program is: t La sortie du programme est :
t t t
Throwing MyException from f()
MyException
        at FullConstructors.f(FullConstructors.java:16)
        at FullConstructors.main(FullConstructors.java:24)
Throwing MyException from g()
MyException: Originated in g()
        at FullConstructors.g(FullConstructors.java:20)
at FullConstructors.main(FullConstructors.java:29)
t
Throwing MyException from f()
MyException
        at FullConstructors.f(FullConstructors.java:16)
        at FullConstructors.main(FullConstructors.java:24)
Throwing MyException from g()
MyException: Originated in g()
        at FullConstructors.g(FullConstructors.java:20)
        at FullConstructors.main(FullConstructors.java:29)
t t t
You can see the absence of the detail message in the MyException thrown from f( ). t Vous Pouvez noter l'absence de message de détail dans le MyException généré depuis f().
t t t
The process of creating your own exceptions can be taken further. You can add extra constructors and members: t La création d'exception personnalisées peut être plus poussée. Vous pouvez ajouter des constructeurs et des membres supplémentaires.
t t t
//: c10:ExtraFeatures.java
// Further embellishment of exception classes.

class MyException2 extends Exception {
  public MyException2() {}
  public MyException2(String msg) {
    super(msg);
  }
  public MyException2(String msg, int x) {
    super(msg);
    i = x;
  }
  public int val() { return i; }
  private int i;
}

public class ExtraFeatures {
  public static void f() throws MyException2 {
    System.out.println(
      "Throwing MyException2 from f()");
    throw new MyException2();
  }
  public static void g() throws MyException2 {
    System.out.println(
      "Throwing MyException2 from g()");
    throw new MyException2("Originated in g()");
  }
  public static void h() throws MyException2 {
    System.out.println(
      "Throwing MyException2 from h()");
    throw new MyException2(
      "Originated in h()", 47);
  }
  public static void main(String[] args) {
    try {
      f();
    } catch(MyException2 e) {
      e.printStackTrace(System.err);
    }
    try {
      g();
    } catch(MyException2 e) {
      e.printStackTrace(System.err);
    }
    try {
      h();
    } catch(MyException2 e) {
      e.printStackTrace(System.err);
      System.err.println("e.val() = " + e.val());
    }
  }
} ///:~
t
//: c10:ExtraFeatures.java
// Further embellishment of exception classes.
class MyException2 "#0000FF">extends Exception {
  public MyException2() {}
  public MyException2(String msg) {
    super(msg);
  }
  public MyException2(String msg, "#0000FF">int x) {
    super(msg);
    i = x;
  }
  public "#0000FF">int val() { return i; }
  private int i;
}
public "#0000FF">class ExtraFeatures {
  public "#0000FF">static void f() "#0000FF">throws MyException2 {
    System.out.println(
      "Throwing MyException2 from f()");
    throw "#0000FF">new MyException2();
  }
  public "#0000FF">static void g() "#0000FF">throws MyException2 {
    System.out.println(
      "Throwing MyException2 from g()");
    throw "#0000FF">new MyException2("#004488">"Originated in g()");
  }
  public "#0000FF">static void h() "#0000FF">throws MyException2 {
    System.out.println(
      "Throwing MyException2 from h()");
    throw "#0000FF">new MyException2(
      "Originated in h()", 47);
  }
  public "#0000FF">static "#0000FF">void main(String[] args) {
    try {
      f();
    } catch(MyException2 e) {
      e.printStackTrace(System.err);
    }
    try {
      g();
    } catch(MyException2 e) {
      e.printStackTrace(System.err);
    }
    try {
      h();
    } catch(MyException2 e) {
      e.printStackTrace(System.err);
      System.err.println("#004488">"e.val() = " + e.val());
    }
  }
} ///:~
t t t
A data member i has been added, along with a method that reads that value and an additional constructor that sets it. The output is: t Un membre i a été ajouté, avec une méthode qui lit cette donnée et un constructeur supplémentaire qui l'initialise. Voici la sortie :
t t t
Throwing MyException2 from f()
MyException2
        at ExtraFeatures.f(ExtraFeatures.java:22)
        at ExtraFeatures.main(ExtraFeatures.java:34)
Throwing MyException2 from g()
MyException2: Originated in g()
        at ExtraFeatures.g(ExtraFeatures.java:26)
        at ExtraFeatures.main(ExtraFeatures.java:39)
Throwing MyException2 from h()
MyException2: Originated in h()
        at ExtraFeatures.h(ExtraFeatures.java:30)
        at ExtraFeatures.main(ExtraFeatures.java:44)
e.val() = 47
t
Throwing MyException2 from f()
MyException2
        at ExtraFeatures.f(ExtraFeatures.java:22)
        at ExtraFeatures.main(ExtraFeatures.java:34)
Throwing MyException2 from g()
MyException2: Originated in g()
        at ExtraFeatures.g(ExtraFeatures.java:26)
        at ExtraFeatures.main(ExtraFeatures.java:39)
Throwing MyException2 from h()
MyException2: Originated in h()
        at ExtraFeatures.h(ExtraFeatures.java:30)
        at ExtraFeatures.main(ExtraFeatures.java:44)
e.val() = 47
t t t
Since an exception is just another kind of object, you can continue this process of embellishing the power of your exception classes. Keep in mind, however, that all this dressing-up might be lost on the client programmers using your packages, since they might simply look for the exception to be thrown and nothing more. (That’s the way most of the Java library exceptions are used.) t Puisqu'une exception est juste une sorte d'objet vous pouvez continuer à enrichir vos classes d'exceptions mais gardez à l'esprit que toutes ces améliorations peuvent êtres ignorées par les clients programmeurs utilisant vos paquettages puisqu'ils vont probablement regarder quelle exception pourra être générée et rien de plus. (C'est de cette façon que sont utilisées le plus souvent les librairies d'exceptions Java).
t t t

The exception specification

t

Spécifier des Exceptions

t t t
In Java, you’re required to inform the client programmer, who calls your method, of the exceptions that might be thrown from your method. This is civilized, because the caller can know exactly what code to write to catch all potential exceptions. Of course, if source code is available, the client programmer could hunt through and look for throw statements, but often a library doesn’t come with sources. To prevent this from being a problem, Java provides syntax (and forces you to use that syntax) to allow you to politely tell the client programmer what exceptions this method throws, so the client programmer can handle them. This is the exception specification, and it’s part of the method declaration, appearing after the argument list. t En java vous êtes obligé de fournir au programmeur qui appelle vos méthodes la liste des exceptions pouvant être générées. C'est correct, en effet le programmeur peut ainsi exactement savoir quel code écrire pour attraper toute exception potentielle. Bien sur si le code source est disponible le programmeur pourra y jeter un Sil et rechercher le mot clé throw, mais souvent une librairie est livrée sans les sources. Pour éviter que Cela soit un problème java fournit une syntaxe (et vous oblige à l'utiliser) qui vous permet d'informer formellement le programmeur client quelle exceptions est générée par cette méthode, pour que le programmeur puisse les gérer. c'est la spécification des exceptions et cela fait partie intégrante de la déclaration de la méthode, elle apparaît après la liste des arguments.
t t t
The exception specification uses an additional keyword, throws, followed by a list of all the potential exception types. So your method definition might look like this: t La spécification des exceptions utilise un nouveau mot clé throws suivi par la liste des type d'exceptions possibles. Vos définitions de méthodes pourront ressembler à ceci :
t t t
void f() throws TooBig, TooSmall, DivZero { //...
t
void f() "#0000FF">throws TooBig, TooSmall, DivZero { "#009900">//...
t t t
If you say

t Si vous écrivez
t t t
void f() { // ...
t
void f() { "#009900">// ...
t t t
it means that no exceptions are thrown
from the method. (Except for the exceptions of type
RuntimeException, which can reasonably be thrown anywhere—this will
be described later.)
t Cela signifie qu'aucune exception en pourra être générée par la méthode. (Excepté les exceptions de type RuntimeException, qui peut être générée n'importe où nous verrons cela plus tard.)
t t t
You can’t lie about an exception
specification—if your method causes exceptions and doesn’t handle
them, the compiler will detect this and tell you that you must either handle the
exception or indicate with an exception specification that it may be thrown from
your method. By enforcing exception specifications from top to bottom, Java
guarantees that exception correctness can be ensured at
compile-time
[52].
t Vous ne pouvez pas mentir à propos de la spécification des exceptions, si votre méthode génère des exceptions sans les gérer le compilateur le détectera et vous dira que vous devez soit gérer ces exceptions ou indiquer en spécifiant que cette exception peut être générée dans votre méthode. En Forçant la spécification des exceptions de haut en bas ,Java garantit que la correction des exceptions est assurée au moment de la compilation.
t t t
There is one place you can lie: you can
claim to throw an exception that you really don’t. The compiler takes your
word for it, and forces the users of your method to treat it as if it really
does throw that exception. This has the beneficial effect of being a placeholder
for that exception, so you can actually start throwing the exception later
without requiring changes to existing code. It’s also important for
creating abstract base classes and interfaces whose derived
classes or implementations may need to throw
exceptions.
t Il y a un endroit ou vous pouvez tricher : vous déclarez générer une exception que vous ne n'allez pas générer. Le compilateur vous prend au pied de la lettre, et force l'utilisateur de la méthode à agir comme si elle pouvait générer l'exception. Ceci à l'effet positif d'être un réceptacle pour cette exception, ainsi vous pourrez générer l'exception sans devoir modifier le code existant. C'. est aussi important pour créer des classes abstraites et des interfaces dont les classes dérivées ou les implémentations puissent générer des exceptions.
t t t


Catching any exception


t

Attraper n'importe quelle exception

t t t
It is possible to create a handler that
catches any type of exception. You do this by catching the base-class exception
type Exception (there are other types of base exceptions, but
Exception is the base that’s pertinent to virtually all programming
activities):

t Il est possible de créer un gestionnaire qui intercepte n'importe quel type d'exception. Ceci est réalisé en interceptant le classe de base d'exception Exception (Il y a d'autre types d'exception de base mais Exception est celle qui est pertinent pour tout les types d'activités de programmation).
t t t
catch(Exception e) {
  System.err.println("Caught an exception");
}
t
catch(Exception e) {
  System.err.println("Caught an exception");
}
t t t
This will catch any exception, so if you use it you’ll want to put it at the end of your list of handlers to avoid preempting any exception handlers that might otherwise follow it. t Ce code interceptera toute les exceptions donc si vous l'utilisez vous voudrez le placer à la fin de votre liste de gestionnaires pour éviter la préemption sur certains gestionnaires qui pourraient dans l'autre cas le suivre.
t t t
Since the Exception class is the base of all the exception classes that are important to the programmer, you don’t get much specific information about the exception, but you can call the methods that come from its base type Throwable: t Comme la classe Exception est la base de toute les classes d'exception qui sont utiles au programmeur, vous n'avez pas beaucoup d'informations spécifiques sur l'exception, mais vous pouvez utiliser les méthode venant de son type de base Throwable :
t t t
String getMessage( )
String
getLocalizedMessage( )Gets the detail message, or a message adjusted for this particular locale.
t String getMessage() String getLocalizedMessage() Donne le message détaillé ou un message adapté à cette localisation particulière.
t t t
String toString( )Returns a short description of the Throwable, including the detail message if there is one. t String toString() Retourne une courte description de l'objet Throwable ,incluant le message détaillé si il y en a un.
t t t
void printStackTrace( )
void printStackTrace(PrintStream)
void
printStackTrace(PrintWriter) Prints the Throwable and the Throwable’s call stack trace. The call stack shows the sequence of method calls that brought you to the point at which the exception was thrown. The first version prints to standard error, the second and third prints to a stream of your choice (in Chapter 11, you’ll understand why there are two types of streams).
t void printStackTrace() void printStackTrace(PrintStream) void printStackTrace(PrintWriter) Imprime l'objet throwable ainsi que la trace de la pile des appels de l'objet Throwable. La pile d'appels vous montre la séquence d'appels de méthodes qui vous ont conduit à l'endroit où l'exception a été levée. La première version imprime les informations vers la sortie standard la seconde et la troisième vers un flux de votre choix (Dans le chapitre 11, vous comprendrez pourquoi il y a deux types de flux).
t t t
Throwable fillInStackTrace( )Records information within this Throwable object about the current state of the stack frames. Useful when an application is rethrowing an error or exception (more about this shortly). t Throwable fillInStackTrace() Enregistre des informations liées à cet objet Throwable concernant l'état de la « stack frame ». Utile quand une application relance une exception (nous approfondirons cela plus loin).
t t t
In addition, you get some other methods from Throwable’s base type Object (everybody’s base type). The one that might come in handy for exceptions is getClass( ), which returns an object representing the class of this object. You can in turn query this Class object for its name with getName( ) or toString( ). You can also do more sophisticated things with Class objects that aren’t necessary in exception handling. Class objects will be studied later in this book. t En plus, vous pouvez utiliser des méthodes provenant de la classe mère de Throwable qui est objet (ancêtre de tout type de base). Celle qui pourrait être utile pour les exceptions est getClass() qui retourne un objet représentant la classe de cet objet. Vous pouvez interroger cet objet de Class avec les méthodes getName() or toString(). Vous pouvez aussi faire des choses plus sophistiquées avec l'objet Class qui ne sont nécessaires dans la gestion des exceptions. Les objets Class seront étudiés plus loin dans ce livre.
t t t
Here’s an example that shows the use of the basic Exception methods: t Voici un exemple qui montre un emploi simple de la méthode d'Exception de base :
t t t
//: c10:ExceptionMethods.java
// Demonstrating the Exception Methods.

public class ExceptionMethods {
  public static void main(String[] args) {
    try {
      throw new Exception("Here's my Exception");
    } catch(Exception e) {
      System.err.println("Caught Exception");
      System.err.println(
        "e.getMessage(): " + e.getMessage());
      System.err.println(
        "e.getLocalizedMessage(): " +
         e.getLocalizedMessage());
      System.err.println("e.toString(): " + e);
      System.err.println("e.printStackTrace():");
      e.printStackTrace(System.err);
    }
  }
} ///:~
t
//: c10:ExceptionMethods.java
// Demonstrating the Exception Methods.
public "#0000FF">class ExceptionMethods {
  public "#0000FF">static "#0000FF">void main(String[] args) {
    try {
      throw "#0000FF">new Exception("#004488">"Here's my Exception");
    } catch(Exception e) {
      System.err.println("Caught Exception");
      System.err.println(
        "e.getMessage(): " + e.getMessage());
      System.err.println(
        "e.getLocalizedMessage(): " +
         e.getLocalizedMessage());
      System.err.println("e.toString(): " + e);
      System.err.println("#004488">"e.printStackTrace():");
      e.printStackTrace(System.err);
    }
  }
} ///:~
t t t
The output for this program is: t La sortie du programme est :
t t t
Caught Exception
e.getMessage(): Here's my Exception
e.getLocalizedMessage(): Here's my Exception
e.toString(): java.lang.Exception:
   Here's my Exception
e.printStackTrace():
java.lang.Exception: Here's my Exception
at ExceptionMethods.main(ExceptionMethods.java:7)
java.lang.Exception:
   Here's my Exception
at ExceptionMethods.main(ExceptionMethods.java:7)
t
Caught Exception
e.getMessage(): Here's my Exception
e.getLocalizedMessage(): Here's my Exception
e.toString(): java.lang.Exception:
   Here's my Exception
e.printStackTrace():
java.lang.Exception: Here's my Exception
at ExceptionMethods.main(ExceptionMethods.java:7)
java.lang.Exception:
   Here's my Exception
at ExceptionMethods.main(ExceptionMethods.java:7)
t t t
You can see that the methods provide successively more information—each is effectively a superset of the previous one. t Vous pouvez observer que les méthodes donnent successivement plus d'informations, chacune est effectivement une évolution de la précédente.
t t t

Rethrowing an exception

t

Relancer une exception

t t t
Sometimes you’ll want to rethrow the exception that you just caught, particularly when you use Exception to catch any exception. Since you already have the reference to the current exception, you can simply rethrow that reference: t Quelques fois vous voudrez relancer une exception que vous venez d'intercepter, particulièrement quand vous utilisez la classe Exception pour attraper n'importe quelle exception. Comme vous avez déjà la référence de l'exception courante vous pouvez tout simplement la re-lancer. >
t t t
catch(Exception e) {
  System.err.println("An exception was thrown");
  throw e;
}
t
catch(Exception e) {
  System.err.println("#004488">"An exception was thrown");
  throw e;
}
t t t
Rethrowing an exception causes the exception to go to the exception handlers in the next-higher context. Any further catch clauses for the same try block are still ignored. In addition, everything about the exception object is preserved, so the handler at the higher context that catches the specific exception type can extract all the information from that object. t La redirection de l'exception envoie l'exception au gestionnaire d'exception de contexte supérieur le plus proche. Tout autre clause catch placée après dans le même bloc try est ignorée. De plus, toute information concernant l'objet exception est préservée, donc le gestionnaire d'exception du niveau supérieur qui peut attraper ce type d'exception spécifique peut extraire toute les informations de cet objet.
t t t
If you simply rethrow the current exception, the information that you print about that exception in printStackTrace( ) will pertain to the exception’s origin, not the place where you rethrow it. If you want to install new stack trace information, you can do so by calling fillInStackTrace( ), which returns an exception object that it creates by stuffing the current stack information into the old exception object. Here’s what it looks like: t Si vous redirigez simplement l'exception courante, l'information que vous restituerez fera référence aux origines de l'exception et non de l'endroit ou vous la redirigez. Si vous voulez placez de nouvelles informations dans la pile des appels, vous pouvez le faire en appelant la méthode fillInStackTrace(), qui retourne un objet exception qu'elle a crée en ajoutant les informations actuelles de la pile dans l'ancien objet exception. Voyons à quoi cela ressemble.
t t t
//: c10:Rethrowing.java
// Demonstrating fillInStackTrace()

public class Rethrowing {
  public static void f() throws Exception {
    System.out.println(
      "originating the exception in f()");
    throw new Exception("thrown from f()");
  }
  public static void g() throws Throwable {
    try {
      f();
    } catch(Exception e) {
      System.err.println(
        "Inside g(), e.printStackTrace()");
      e.printStackTrace(System.err);
      throw e; // 17
      // throw e.fillInStackTrace(); // 18
    }
  }
  public static void
  main(String[] args) throws Throwable {
    try {
      g();
    } catch(Exception e) {
      System.err.println(
        "Caught in main, e.printStackTrace()");
      e.printStackTrace(System.err);
    }
  }
} ///:~
t
//: c10:Rethrowing.java
// Demonstrating fillInStackTrace()
public "#0000FF">class Rethrowing {
  public "#0000FF">static void f() "#0000FF">throws Exception {
    System.out.println(
      "originating the exception in f()");
    throw "#0000FF">new Exception("#004488">"thrown from f()");
  }
  public "#0000FF">static void g() "#0000FF">throws Throwable {
    try {
      f();
    } catch(Exception e) {
      System.err.println(
        "Inside g(), e.printStackTrace()");
      e.printStackTrace(System.err);
      throw e; "#009900">// 17
      // throw e.fillInStackTrace(); // 18
    }
  }
  public "#0000FF">static void
  main(String[] args) throws Throwable {
    try {
      g();
    } catch(Exception e) {
      System.err.println(
        "Caught in main, e.printStackTrace()");
      e.printStackTrace(System.err);
    }
  }
} ///:~
t t t
The important line numbers are marked as comments. With line 17 uncommented (as shown), the output is: t Les numéros des lignes importantes sont marquées dans les commentaires, avec la ligne 17 non mise en commentaire (cf. le code ci-dessus) l'exécution produit comme sortie :
t t t
originating the exception in f()
Inside g(), e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:8)
        at Rethrowing.g(Rethrowing.java:12)
        at Rethrowing.main(Rethrowing.java:24)
Caught in main, e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:8)
        at Rethrowing.g(Rethrowing.java:12)
at Rethrowing.main(Rethrowing.java:24)
t
originating the exception in f()
Inside g(), e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:8)
        at Rethrowing.g(Rethrowing.java:12)
        at Rethrowing.main(Rethrowing.java:24)
Caught in main, e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:8)
        at Rethrowing.g(Rethrowing.java:12)
        at Rethrowing.main(Rethrowing.java:24)
t t t
So the exception stack trace always remembers its true point of origin, no matter how many times it gets rethrown. t Ainsi la trace de la pile d'exception se souvient toujours de sont vrai point d'origine, sans tenir compte du nombre de fois qu'il sera relancé.
t t t
With line 17 commented and line 18 uncommented, fillInStackTrace( ) is used instead, and the result is: t Avec la ligne 17 mise en commentaire et la ligne 18 décommentée fillInStackTrace() est utilisée ce qui donne le résultat suivant :
t t t
originating the exception in f()
Inside g(), e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:8)
        at Rethrowing.g(Rethrowing.java:12)
        at Rethrowing.main(Rethrowing.java:24)
Caught in main, e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.g(Rethrowing.java:18)
at Rethrowing.main(Rethrowing.java:24)
t
originating the exception in f()
Inside g(), e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:8)
        at Rethrowing.g(Rethrowing.java:12)
        at Rethrowing.main(Rethrowing.java:24)
Caught in main, e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.g(Rethrowing.java:18)
        at Rethrowing.main(Rethrowing.java:24)
t t t
Because of fillInStackTrace( ), line 18 becomes the new point of origin of the exception. t Grâce à fillInStackTrace() la ligne 18 devient l'origine de l'exception.
t t t
The class Throwable must appear in the exception specification for g( ) and main( ) because fillInStackTrace( ) produces a reference to a Throwable object. Since Throwable is a base class of Exception, it’s possible to get an object that’s a Throwable but not an Exception, so the handler for Exception in main( ) might miss it. To make sure everything is in order, the compiler forces an exception specification for Throwable. For example, the exception in the following program is not caught in main( ): t La classe Throwable doit apparaître dans la spécification d'exception pour g() et main() parce que fillInStackTrace() produit une référence à un objet Throwable. Comme Throwable est la classe de base de toute Exception il est possible d'avoir un objet de type Throwable qui ne soit pas une Exception et donc que le gestionnaire d'exception du main() ne le traite pas. Pour être sur que tout soit correct le compilateur force une spécification d'exception pour Throwable. Par exemple l'exception dans le programme suivant n'est pas interceptée dans main() :
t t t
//: c10:ThrowOut.java
public class ThrowOut {
  public static void
  main(String[] args) throws Throwable {
    try {
      throw new Throwable();
    } catch(Exception e) {
      System.err.println("Caught in main()");
    }
  }
} ///:~
t
//: c10:ThrowOut.java
public "#0000FF">class ThrowOut {
  public "#0000FF">static void
  main(String[] args) throws Throwable {
    try {
      throw "#0000FF">new Throwable();
    } catch(Exception e) {
      System.err.println("Caught in main()");
    }
  }
} ///:~
t t t
It’s also possible to rethrow a different exception from the one you caught. If you do this, you get a similar effect as when you use fillInStackTrace( )—the information about the original site of the exception is lost, and what you’re left with is the information pertaining to the new throw: t Il est aussi possible de rediriger une exception différente de celle que vous avez intercepté. En procédant ainsi vous obtenez une effet similaire a l'utilisation de fillInStackTrace() . l'information sur l'emplacement originel de l'exception est perdu, et l'information qu'il vous reste est celle relative au nouveau throw() :
t t t
//: c10:RethrowNew.java
// Rethrow a different object
// from the one that was caught.

class OneException extends Exception {
  public OneException(String s) { super(s); }
}

class TwoException extends Exception {
  public TwoException(String s) { super(s); }
}

public class RethrowNew {
  public static void f() throws OneException {
    System.out.println(
      "originating the exception in f()");
    throw new OneException("thrown from f()");
  }
  public static void main(String[] args)
  throws TwoException {
    try {
      f();
    } catch(OneException e) {
      System.err.println(
        "Caught in main, e.printStackTrace()");
      e.printStackTrace(System.err);
      throw new TwoException("from main()");
    }
  }
} ///:~
t
//: c10:RethrowNew.java
// Rethrow a different object
// from the one that was caught.
class OneException "#0000FF">extends Exception {
  public OneException(String s) { "#0000FF">super(s); }
}
class TwoException "#0000FF">extends Exception {
  public TwoException(String s) { "#0000FF">super(s); }
}
public "#0000FF">class RethrowNew {
  public "#0000FF">static void f() "#0000FF">throws OneException {
    System.out.println(
      "originating the exception in f()");
    throw "#0000FF">new OneException("#004488">"thrown from f()");
  }
  public "#0000FF">static "#0000FF">void main(String[] args)
  throws TwoException {
    try {
      f();
    } catch(OneException e) {
      System.err.println(
        "Caught in main, e.printStackTrace()");
      e.printStackTrace(System.err);
      throw "#0000FF">new TwoException("#004488">"from main()");
    }
  }
} ///:~
t t t
The output is: t Le résultat de l'exécution est :
t t t
originating the exception in f()
Caught in main, e.printStackTrace()
OneException: thrown from f()
        at RethrowNew.f(RethrowNew.java:17)
        at RethrowNew.main(RethrowNew.java:22)
Exception in thread "main" TwoException: from main()
at RethrowNew.main(RethrowNew.java:27)
t
originating the exception in f()
Caught in main, e.printStackTrace()
OneException: thrown from f()
        at RethrowNew.f(RethrowNew.java:17)
        at RethrowNew.main(RethrowNew.java:22)
Exception in thread "#004488">"main" TwoException: from main()
        at RethrowNew.main(RethrowNew.java:27)
t t t
The final exception knows only that it came from main( ), and not from f( ). t L'exception finale sait seulement qu'elle vient de main() et non de f().
t t t
You never have to worry about cleaning up the previous exception, or any exceptions for that matter. They’re all heap-based objects created with new, so the garbage collector automatically cleans them all up. t Vous n'avez pas à vous soucier de la destruction des exceptions précédentes. Ce sont tout des objets crées avec l'instruction new(), le garbage collector les détruits donc automatiquement.
t t t

Standard Java exceptions

t

Les exceptions Java standard

t t t
The Java class Throwable describes anything that can be thrown as an exception. There are two general types of Throwable objects (“types of” = “inherited from”). Error represents compile-time and system errors that you don’t worry about catching (except in special cases). Exception is the basic type that can be thrown from any of the standard Java library class methods and from your methods and run-time accidents. So the Java programmer’s base type of interest is Exception. t La classe Java Throwable décrit tout ce qui peut être généré comme exception. Il y a deux sortes d'objets Throwable (« Sortes de » = « Héritées de »). Error représente les erreurs systèmes et de compilation dont vous n'avez pas à vous soucier (excepté quelques cas spécifiques). Exception est le type de base qui peut être généré à partir de n'importe quelle méthode de classe de librairie Java standard. Les Exceptions sont donc le type de base qui intéresse le programmeur Java.
t t t
The best way to get an overview of the exceptions is to browse the HTML Java documentation that you can download from java.sun.com. It’s worth doing this once just to get a feel for the various exceptions, but you’ll soon see that there isn’t anything special between one exception and the next except for the name. Also, the number of exceptions in Java keeps expanding; basically it’s pointless to print them in a book. Any new library you get from a third-party vendor will probably have its own exceptions as well. The important thing to understand is the concept and what you should do with the exceptions. t La meilleure façon d'avoir un aperçu des exceptions est de lire la documentation HTML de Java qui est disponible à java.sun.com. Il est utile de le faire juste pour s'apercevoir de la variété des exception, mais vous verrez rapidement que rien à part le nom ne distingue une exception d'une autre. Comme le nombre d'exceptions Java continue de s'accroître il est inutile d'en imprimer la liste. Chaque nouvelle librairie que vous achèterez à un éditeur aura probablement ses propres exceptions. Le point important à comprendre est le concept et ce que vous devez faire avec les exceptions.
t t t
The basic idea is that the name of the exception represents the problem that occurred, and the exception name is intended to be relatively self-explanatory. The exceptions are not all defined in java.lang; some are created to support other libraries such as util, net, and io, which you can see from their full class names or what they are inherited from. For example, all I/O exceptions are inherited from java.io.IOException. t Le principe de base est que le nom de l'exception représente le problème qui est apparu, et le nom de l'exception est censé être relativement explicite. Toutes les exceptions ne sont pas toutes définies dans java.lang ; certaines ont été crées pour être utilisées dans d'autres libraires telles que util, net et io ce que l'on peut voir à partir du nom complet des classes dont elles ont héritées. Ainsi toutes les exception I/O (Entrée/Sortie) héritent de java.io.IOException.
t t t

The special case of RuntimeException

t

Le cas particulier RuntimeException

t t t
The first example in this chapter was t Le premier exemple du chapitre était :
t t t
if(t == null)
throw new NullPointerException();
t
if(t == "#0000FF">null)
  throw "#0000FF">new NullPointerException();
t t t
t t t
t t
    
///
t t t
t
     
Sommaire Le site de Bruce Eckel