Meilleures pratiques Java lors du lancement d'exceptions: lancer des exceptions Java de base
Au lieu de lancer new Exception("Some message", maybeSomeCause)
, ce qui signifie que tous les appelants de ma méthode devront attraper Exception (qui peut inclure RuntimeExceptions), je voudrais lancer un type d'exception plus spécifique lorsqu'un problème se produit.
Je peux créer mes propres types d'exception qui étendent Exception ou un autre type d'exception, mais je suis curieux de savoir si c'est une bonne idée de réutiliser certaines exceptions qui viennent avec le langage Java de base, comme comme:
- IllegalArgumentException
- UnsupportedOperationException
- IOException
- autres?
Y en a-t-il d'autres qui me manquent? J'ai trouvé une liste de base des exceptions 'core' ici: http://rymden.nu/exceptions.html , avec des explications humiques.
Merci!
Modifier:
Existe-t-il une bonne liste d'exceptions 'principales'?
Liste donc loin:
5 réponses
Oui, c'est très bien de le faire. En fait, il est même écrit à propos de Effective Java, 2nd ed. Voir l'article 60 à la page 248: "favoriser l'utilisation d'exceptions standard"
La réutilisation d'exceptions préexistantes présente plusieurs avantages. Chef d'entre ceux-ci, il rend votre API plus facile à apprendre et à utiliser car il correspond conventions établies avec lesquelles les programmeurs sont déjà familiers. Un fermer deuxièmement est que les programmes utilisant votre API sont plus faciles à lire parce qu'ils ne sont pas encombrés avec des exceptions inconnues. La dernière (et moins), moins de classes d'exception signifient une empreinte mémoire plus petite et moins de temps passé à charger les classes.
Les listes fournies dans votre question ne sont pas très utilisables comme matériel de référence rapide, et la plupart des descriptions dans les documents de développement me semblent cryptiques.
Je n'ai rencontré aucune liste courte des exceptions intégrées les plus réutilisables. J'ai fait de mon mieux pour en créer un ci-dessous, mais je suis sûr que c'est loin d'être parfait.
GitHub gist link (ou voir le contenu actuel ci-dessous)
Liste des Exceptions intégrées potentiellement réutilisables
Organisé par estimé utilitaire
IllegalArgumentException
Jeté pour indiquer qu'une méthode a été adoptée un argument illégal ou inapproprié.
IndexOutOfBoundsException
Jeté pour indiquer qu'un index quelconque (comme un tableau, une chaîne ou un vecteur) est hors de portée.
ArithmeticException
Lancé lorsque l'opération mathématique demandée est non-sensicale ou impossible.
exemple: int x = 1/0
;
IllegalStateException
Le l'application n'est pas dans un état approprié à l'opération demandée. exemple: essayer d'enregistrer avant le chargement ou la création du fichier.
DataFormatException
Lancez ceci lorsque vous avez reçu des données mal formatées.
exemple: MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")
TimeoutException
Jetez ceci si quelque chose a pris trop de temps et que vous abandonnez.
KeySelectorException
Je pense qu'il est logique de lancer ceci si vous essayez de chercher un objet en utilisant une clé et c'était non trouvé ou la clé est autrement invalide, mais je ne comprends pas vraiment les dev docs dessus.
Exemple: myDataStructure.get("lookup_key");
lorsque lookup_key
n'est pas dans la structure de données.
IOException
Avoir un problème de lecture/écriture? Jetez cette exception.
ScriptException
Exécuter un script d'une certaine forme et trouvé un problème avec lui (pas d'E/S ou d'analyse)? Jetez cette exception.
GeneralSecurityException
Jetez ceci si vous rencontrez un problème de sécurité.
RuntimeException
Utilisez ceci pour une erreur d'exécution qui ne correspond pas bien à une autre catégorie.
Il est absolument logique de réutiliser les classes Exception
lorsqu'elles décrivent raisonnablement le scénario qui a provoqué la levée de l'exception.
La plupart des exceptions de base sont trop spécialisées pour être utilisées directement, sauf si vous dupliquez des fonctionnalités existantes dans les bibliothèques de base. Par exemple, vous n'aurez probablement jamais besoin de créer une instance de UnknownHostException
; si la résolution de l'hôte échoue, la méthode InetAddress
ou SocketFactory
que vous avez appelée aurait déjà créé et lancé l'exception.
Les seules exceptions que j'ai trouvé pour être généralement utilisables sont IOException
, IllegalArgumentException
, IllegalStateException
, et UnsupportedOperationException
.
IOException
- Tous les problèmes avec les interfaces, la mise en réseau et l'accès au disque dur tombe sous cette. Si vous écrivez du code pour accéder aux données externes ou au matériel, vous devriez l'utiliser. Par exemple, si vous implémentez une API pour accéder à un certain type de périphérique réseau, vous pouvez lancer une sous-classe MyDeviceException
lorsque le périphérique renvoie un statut d'erreur ou fait quelque chose d'étrange. Il y a aussi des cas où vous voulez attraper un IOException
à partir d'un ou plusieurs appels de bibliothèque de bas niveau et l'envelopper dans un autre IOException
avec un message de niveau supérieur, tel qu'un vérification de la connectivité lancer une exception "périphérique non disponible" causée par une exception" demande expirée".
IllegalArgumentException
- Toutes les vérifications de paramètres devraient lancer ceci. Par exemple, un entier négatif pour un paramètre de taille, ou un imprévu null
. C'est une exception non cochée, mais je recommande de la documenter de toute façon pour rendre les conditions préalables de la méthode plus claires. Vous pouvez trouver beaucoup d'exemples dans les bibliothèques de base.
IllegalStateException
- Vous pouvez l'utiliser lorsque les paramètres de méthode sont valides, mais certains les données internes ou les fonctionnalités requises par la méthode ne sont pas disponibles, et il n'y a pas d'exception vérifiée plus appropriée (comme IOException
). Il est souvent préférable de concevoir des choses de sorte que ce n'est pas nécessaire.
UnsupportedOperationException
- Si vous créez une sous-classe de quelque chose et que l'une des méthodes de superclasse est conceptuellement invalide, remplacez-la et lancez-en une. Guava l'utilise pour ses classes de collection immuables , puisque les interfaces de collection de Java ne sont pas conçues pour supporter l'immutabilité. Cela tend à être un signe de mauvaise conception dans la superclasse. Ne l'utilisez pas si ne rien faire ou renvoyer null / empty serait un résultat approprié et sans surprise.
Si les utilisateurs de votre code peuvent avoir besoin de faire des choses différentes sur deux exceptions différentes, alors ceux-ci devraient être des types d'exception distincts. Cela dit, les exceptions JDK couvrent la plupart des exceptions "erreur de programmeur" - si un IllegalArgumentException
est lancé, par exemple, cela indique une erreur de programmation, pas quelque chose qui devrait être géré au moment de l'exécution.