Exceptions personnalisées
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 60 sur 87.
Les exceptions intégrées de Java couvrent de nombreux scénarios d'erreur courants, mais vous avez parfois besoin d'exceptions spécifiques au domaine de votre application. Les exceptions personnalisées vous permettent de créer des types d'erreurs significatifs qui communiquent clairement ce qui s'est mal passé.
Pour créer une exception personnalisée, étendez simplement une classe d'exception existante. Pour une exception contrôlée, étendez Exception :
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}Pour une exception non contrôlée, étendez RuntimeException :
public class InvalidAgeException extends RuntimeException {
public InvalidAgeException(String message) {
super(message);
}
}L'appel super(message) transmet le message d'erreur à la classe parente, le rendant disponible via getMessage(). Vous pouvez ensuite lever et intercepter votre exception personnalisée comme n'importe quelle autre :
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException("Balance too low: " + balance);
}
balance -= amount;
}
// Utilisation
try {
account.withdraw(1000);
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
}Les exceptions personnalisées rendent votre code plus lisible et permettent aux appelants de gérer différemment des conditions d'erreur spécifiques. Elles sont particulièrement précieuses lors de la création d'API ou de bibliothèques où une communication claire des erreurs est importante.
Défi
FacileConstruisons un système de réservation de billets qui utilise des exceptions personnalisées pour gérer différents scénarios d'erreur ! Vous allez créer des types d'exceptions significatifs qui communiquent clairement ce qui s'est mal passé lors de la réservation des billets.
Vous organiserez votre code sur quatre fichiers :
TicketSoldOutException.java: Créez une exception vérifiée (checked exception) personnalisée (étendException) pour les cas où les billets ne sont plus disponibles. Votre exception doit accepter un message dans son constructeur et le transmettre à la classe parente en utilisantsuper(message).InvalidSeatException.java: Créez une exception non vérifiée (unchecked exception) personnalisée (étendRuntimeException) pour les cas où quelqu'un essaie de réserver un numéro de siège invalide. Cette exception doit également accepter et transmettre un message à son parent.TicketBooth.java: Créez une classe qui gère la vente des billets. Votre guichet doit suivre le nombre total de sièges disponibles et le numéro de siège valide le plus élevé. Incluez :Un constructeur qui prend le nombre total de sièges disponibles.
Une méthode
bookTicket(int seatNumber)qui valide la réservation. S'il ne reste plus de billets (les sièges disponibles sont de 0 ou moins), lancez uneTicketSoldOutExceptionavec le message"No tickets remaining". Si le numéro de siège est inférieur à 1 ou supérieur au nombre total de sièges, lancez uneInvalidSeatExceptionavec le message"Seat " + seatNumber + " does not exist". Sinon, diminuez les sièges disponibles de 1 et affichez"Booked seat " + seatNumber + " successfully".Une méthode
getAvailableSeats()qui retourne le nombre actuel de sièges disponibles.Main.java: Rassemblez votre système de billetterie ! Vous recevrez deux entrées : le nombre total de sièges et un numéro de siège à réserver.Créez un
TicketBoothavec le nombre total de sièges donné. Tentez ensuite de réserver le numéro de siège spécifié à l'intérieur d'un bloc try-catch. CommeTicketSoldOutExceptionest une exception vérifiée, vous devez la gérer. Interceptez d'abordTicketSoldOutExceptionet affichez"Booking failed: " + e.getMessage(). Interceptez ensuiteInvalidSeatExceptionet affichez le même format :"Booking failed: " + e.getMessage().Après le bloc try-catch, affichez
"Remaining seats: " + booth.getAvailableSeats()en utilisant la méthode getter.
Vous recevrez deux entrées dans l'ordre : le nombre total de sièges (entier) et le numéro de siège à réserver (entier).
Remarquez comment les exceptions vérifiées obligent les appelants à les gérer (avec try-catch ou throws), tandis que les exceptions non vérifiées ne nécessitent pas de gestion explicite. Choisissez le type d'exception selon que l'erreur est quelque chose que les appelants doivent anticiper et dont ils doivent se remettre !
Aide-mémoire
Pour créer une exception personnalisée, étendez une classe d'exception existante.
Pour une exception contrôlée (checked exception), étendez Exception :
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}Pour une exception non contrôlée (unchecked exception), étendez RuntimeException :
public class InvalidAgeException extends RuntimeException {
public InvalidAgeException(String message) {
super(message);
}
}L'appel super(message) transmet le message d'erreur à la classe parente, le rendant disponible via getMessage().
Lancez et capturez des exceptions personnalisées comme n'importe quelle autre exception :
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException("Balance too low: " + balance);
}
balance -= amount;
}
// Using it
try {
account.withdraw(1000);
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
}Les exceptions contrôlées obligent les appelants à les gérer avec try-catch ou throws. Les exceptions non contrôlées ne nécessitent pas de gestion explicite. Choisissez en fonction de si l'erreur est quelque chose que les appelants devraient anticiper et dont ils devraient se rétablir.
Essayez vous-même
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int totalSeats = scanner.nextInt();
int seatNumber = scanner.nextInt();
// TODO: Créer un TicketBooth avec le nombre total de sièges donné
// TODO: Utiliser un bloc try-catch pour tenter de réserver le siège
// - Attraper TicketSoldOutException en premier et afficher "Booking failed: [exception message]"
// - Attraper InvalidSeatException et afficher "Booking failed: [exception message]"
// TODO: Après le try-catch, afficher "Remaining seats: [count]"
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé10Gestion des exceptions en POO
Hiérarchie des classes d'exceptionExceptions personnaliséesErreurs Checked vs UncheckedPattern Try-with-resourcesRécapitulatif - Utilisateur validé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron Itérateur