Question

En Java (ou dans tout autre langage avec des exceptions vérifiées), lors de la création de votre propre classe d'exceptions, comment décidez-vous si elle doit être cochée ou décochée ?

Mon instinct est de dire qu'une exception vérifiée serait nécessaire dans les cas où l'appelant pourrait être en mesure de récupérer de manière productive, alors qu'une exception non vérifiée serait davantage destinée aux cas irrécupérables, mais je serais intéressé par les pensées des autres.

Était-ce utile?

La solution

Les exceptions vérifiées sont excellentes, à condition que vous compreniez quand elles doivent être utilisées.L'API principale Java ne parvient pas à suivre ces règles pour SQLException (et parfois pour IOException), c'est pourquoi elles sont si terribles.

Exceptions vérifiées devrait être utilisé pour prévisible, mais inévitable les erreurs qui sont raisonnable de se remettre de.

Exceptions non vérifiées devrait être utilisé pour tout le reste.

Je vais vous expliquer cela, car la plupart des gens ne comprennent pas ce que cela signifie.

  1. Prévisible mais inévitable:L'appelant a fait tout ce qui était en son pouvoir pour valider les paramètres d'entrée, mais une condition indépendante de sa volonté a provoqué l'échec de l'opération.Par exemple, vous essayez de lire un fichier mais quelqu'un le supprime entre le moment où vous vérifiez s'il existe et le moment où l'opération de lecture commence.En déclarant une exception vérifiée, vous dites à l'appelant d'anticiper cet échec.
  2. Il est raisonnable de se remettre de:Il ne sert à rien de dire aux appelants d’anticiper les exceptions dont ils ne peuvent pas se remettre.Si un utilisateur tente de lire un fichier inexistant, l'appelant peut lui demander un nouveau nom de fichier.D'un autre côté, si la méthode échoue en raison d'un bug de programmation (arguments de méthode invalides ou implémentation de méthode boguée), l'application ne peut rien faire pour résoudre le problème en cours d'exécution.Le mieux qu'il puisse faire est de consigner le problème et d'attendre que le développeur le résolve ultérieurement.

À moins que l'exception que vous lancez ne réponde tous des conditions ci-dessus, il doit utiliser une exception non vérifiée.

Réévaluer à tous les niveaux:Parfois, la méthode qui intercepte l’exception vérifiée n’est pas le bon endroit pour gérer l’erreur.Dans ce cas, réfléchissez à ce qui est raisonnable pour vos propres appelants.Si l'exception est prévisible, inévitable et raisonnable pour qu'ils puissent s'en remettre, vous devez lancer vous-même une exception vérifiée.Sinon, vous devez envelopper l'exception dans une exception non cochée.Si vous suivez cette règle, vous vous retrouverez à convertir les exceptions vérifiées en exceptions non vérifiées et vice versa en fonction de la couche dans laquelle vous vous trouvez.

Pour les exceptions cochées et non cochées, utiliser le bon niveau d'abstraction.Par exemple, un référentiel de code avec deux implémentations différentes (base de données et système de fichiers) devrait éviter d'exposer les détails spécifiques à l'implémentation en lançant SQLException ou IOException.Au lieu de cela, il devrait envelopper l'exception dans une abstraction qui couvre toutes les implémentations (par ex. RepositoryException).

Autres conseils

Depuis Un apprenant Java:

Lorsqu'une exception se produit, vous devez soit attraper et gérer l'exception, soit dire au compilateur que vous ne pouvez pas le gérer en déclarant que votre méthode lance cette exception, alors le code qui utilise votre méthode devra gérer cette exception (même elle Peut également choisir de déclarer qu'il lance l'exception s'il ne peut pas le gérer).

Le compilateur vérifie que nous avons fait l'une des deux choses (attraper ou déclarer).Ils sont donc appelés exceptions vérifiées.Mais les erreurs et les exceptions d'exécution ne sont pas vérifiées par le compilateur (même si vous pouvez choisir d'attraper ou de déclarer, ce n'est pas nécessaire).Ainsi, ces deux-là sont appelés exceptions incontrôlées.

Des erreurs sont utilisées pour représenter les conditions qui se produisent en dehors de l'application, telles que le crash du système.Des exceptions d'exécution sont généralement survenues par défaut dans la logique d'application.Vous ne pouvez rien faire dans ces situations.Lorsque l'exception d'exécution se produit, vous devez réécrire votre code de programme.Donc, ceux-ci ne sont pas vérifiés par le compilateur.Ces exceptions d'exécution se révèlent en développement et en période de test.Ensuite, nous devons refacter notre code pour supprimer ces erreurs.

La règle que j'utilise est la suivante :n'utilisez jamais d'exceptions non vérifiées !(ou quand vous ne voyez aucun moyen de contourner ce problème)

Il existe de très solides arguments en faveur du contraire :N’utilisez jamais d’exceptions vérifiées.Je suis réticent à prendre parti dans le débat, mais il semble y avoir un large consensus sur le fait que l'introduction d'exceptions vérifiées était une mauvaise décision avec le recul.S'il vous plaît, ne tirez pas sur le messager et référez-vous à ceux arguments.

Sur tout système suffisamment grand, avec de nombreuses couches, les exceptions vérifiées sont inutiles car, de toute façon, vous avez besoin d'une stratégie au niveau architectural pour gérer la façon dont l'exception sera gérée (utilisez une barrière de panne)

Avec les exceptions vérifiées, votre stratégie de gestion des erreurs est micro-gérée et insupportable sur n'importe quel grand système.

La plupart du temps vous ne savez pas si une erreur est "récupérable" car vous ne savez pas dans quelle couche se situe l'appelant de votre API.

Disons que je crée une API StringToInt qui convertit la représentation sous forme de chaîne d'un entier en Int.Dois-je lancer une exception vérifiée si l'API est appelée avec la chaîne "foo" ?Est-ce récupérable ?Je ne sais pas car dans sa couche l'appelant de mon API StringToInt a peut-être déjà validé l'entrée, et si cette exception est levée, c'est soit un bug, soit une corruption de données et elle n'est pas récupérable pour cette couche.

Dans ce cas, l'appelant de l'API ne souhaite pas intercepter l'exception.Il veut seulement laisser l'exception « bouillonner ».Si j'ai choisi une exception vérifiée, cet appelant aura beaucoup de blocs catch inutiles uniquement pour relancer artificiellement l'exception.

Ce qui est récupérable dépend la plupart du temps de l'appelant de l'API, et non de l'auteur de l'API.Une API ne doit pas utiliser d'exceptions vérifiées, car seules les exceptions non vérifiées permettent de choisir d'intercepter ou d'ignorer une exception.

Tu as raison.

Exceptions non vérifiées sont utilisés pour laisser le système échouer rapidement Ce qui est une bonne chose.Vous devez indiquer clairement ce que votre méthode attend pour fonctionner correctement.De cette façon, vous ne pouvez valider la saisie qu'une seule fois.

Par exemple:

/**
 * @params operation - The operation to execute.
 * @throws IllegalArgumentException if the operation is "exit"
 */
 public final void execute( String operation ) {
     if( "exit".equals(operation)){
          throw new IllegalArgumentException("I told you not to...");
     }
     this.operation = operation; 
     .....  
 }
 private void secretCode(){
      // we perform the operation.
      // at this point the opreation was validated already.
      // so we don't worry that operation is "exit"
      .....  
 }

Juste pour mettre un exemple.Le fait est que si le système tombe en panne rapidement, vous saurez alors où et pourquoi il a échoué.Vous obtiendrez un stacktrace comme :

 IllegalArgumentException: I told you not to use "exit" 
 at some.package.AClass.execute(Aclass.java:5)
 at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569)
 ar ......

Et vous saurez ce qui s'est passé.La OtherClass dans la méthode "delegateTheWork" (à la ligne 4569) a appelé votre classe avec la valeur "exit", même si elle ne devrait pas, etc.

Sinon, vous devrez répartir les validations partout dans votre code, ce qui est sujet aux erreurs.De plus, il est parfois difficile de suivre ce qui n'a pas fonctionné et vous pouvez vous attendre à des heures de débogage frustrant.

La même chose se produit avec NullPointerExceptions.Si vous avez une classe de 700 lignes avec une quinzaine de méthodes, qui utilise 30 attributs et qu'aucun d'entre eux ne peut être nul, au lieu de valider la nullité dans chacune de ces méthodes, vous pouvez rendre tous ces attributs en lecture seule et les valider dans le constructeur ou méthode d'usine.

 public static MyClass createInstane( Object data1, Object data2 /* etc */ ){ 
      if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); }

  }


  // the rest of the methods don't validate data1 anymore.
  public void method1(){ // don't worry, nothing is null 
      ....
  }
  public void method2(){ // don't worry, nothing is null 
      ....
  }
  public void method3(){ // don't worry, nothing is null 
      ....
  }

Exceptions vérifiées Sont utiles lorsque le programmeur (vous ou vos collègues) a tout fait correctement, a validé l'entrée, exécuté des tests et que tout le code est parfait, mais que le code se connecte à un service Web tiers qui peut être en panne (ou à un fichier que vous étiez using a été supprimé par un autre processus externe, etc.).Le service Web peut même être validé avant la tentative de connexion, mais pendant le transfert de données, quelque chose s'est mal passé.

Dans ce scénario, vous ou vos collègues ne pouvez rien faire pour y remédier.Mais il faut quand même faire quelque chose et ne pas laisser l’application mourir et disparaître aux yeux de l’utilisateur.Vous utilisez une exception vérifiée pour cela et gérez l'exception, que pouvez-vous faire lorsque cela se produit ?, la plupart du temps, juste pour tenter de consigner l'erreur, enregistrez probablement votre travail (l'application fonctionne) et présentez un message à l'utilisateur. .(Le site blabla est en panne, merci de réessayer plus tard etc.)

Si les exceptions vérifiées sont surutilisées (en ajoutant "throw Exception" dans toutes les signatures de méthodes), alors votre code deviendra très fragile, car tout le monde ignorera cette exception (car elle est trop générale) et la qualité du code sera sérieusement affectée. compromis.

Si vous abusez d’une exception non contrôlée, quelque chose de similaire se produira.Les utilisateurs de ce code ne savent pas si quelque chose peut mal se passer et de nombreux try{...}catch( Throwable t ) apparaîtront.

Voici ma « règle générale finale ».
J'utilise:

  • exception non vérifiée dans le code de ma méthode pour un échec dû à l'appelant (cela implique un documentation explicite et complète)
  • exception vérifiée pour un échec dû à appelé que je dois expliquer à toute personne souhaitant utiliser mon code

Par rapport à la réponse précédente, il s’agit d’une justification claire (sur laquelle on peut être d’accord ou en désaccord) pour le recours à l’un ou l’autre (ou aux deux) types d’exceptions.


Pour ces deux exceptions, je créerai ma propre exception non cochée et cochée pour mon application (une bonne pratique, comme mentionné ici), à l'exception des exceptions non vérifiées très courantes (comme NullPointerException)

Ainsi, par exemple, le but de cette fonction particulière ci-dessous est de créer (ou d'obtenir s'il existe déjà) un objet,
signification:

  • le conteneur de l'objet à fabriquer/obtenir DOIT exister (responsabilité de l'APPELANT
    => exception non vérifiée, ET commentaire javadoc clair pour cette fonction appelée)
  • les autres paramètres ne peuvent pas être nuls
    (choix du codeur pour mettre ça sur l'APPELANT :le codeur ne vérifiera pas le paramètre nul mais le codeur LE DOCUMENTE)
  • le résultat NE PEUT PAS ÊTRE NULL
    (responsabilité et choix du code de l'appelé, choix qui sera d'un grand intérêt pour l'appelant
    => exception vérifiée car tous les appelants DOIVENT prendre une décision si l'objet ne peut pas être créé/trouvé, et cette décision doit être appliquée au moment de la compilation :ils ne peuvent pas utiliser cette fonction sans avoir à gérer cette possibilité, c'est-à-dire à cela vérifié exception).

Exemple:


/**
 * Build a folder. <br />
 * Folder located under a Parent Folder (either RootFolder or an existing Folder)
 * @param aFolderName name of folder
 * @param aPVob project vob containing folder (MUST NOT BE NULL)
 * @param aParent parent folder containing folder 
 *        (MUST NOT BE NULL, MUST BE IN THE SAME PVOB than aPvob)
 * @param aComment comment for folder (MUST NOT BE NULL)
 * @return a new folder or an existing one
 * @throws CCException if any problems occurs during folder creation
 * @throws AssertionFailedException if aParent is not in the same PVob
 * @throws NullPointerException if aPVob or aParent or aComment is null
 */
static public Folder makeOrGetFolder(final String aFoldername, final Folder aParent,
    final IPVob aPVob, final Comment aComment) throws CCException {
    Folder aFolderRes = null;
    if (aPVob.equals(aParent.getPVob() == false) { 
       // UNCHECKED EXCEPTION because the caller failed to live up
       // to the documented entry criteria for this function
       Assert.isLegal(false, "parent Folder must be in the same PVob than " + aPVob); }

    final String ctcmd = "mkfolder " + aComment.getCommentOption() + 
        " -in " + getPNameFromRepoObject(aParent) + " " + aPVob.getFullName(aFolderName);

    final Status st = getCleartool().executeCmd(ctcmd);

    if (st.status || StringUtils.strictContains(st.message,"already exists.")) {
        aFolderRes = Folder.getFolder(aFolderName, aPVob);
    }
    else {
        // CHECKED EXCEPTION because the callee failed to respect his contract
        throw new CCException.Error("Unable to make/get folder '" + aFolderName + "'");
    }
    return aFolderRes;
}

Ce n’est pas seulement une question de capacité à se remettre de l’exception.Ce qui compte le plus, à mon avis, c'est de savoir si l'appelant souhaite ou non détecter l'exception.

Si vous écrivez une bibliothèque à utiliser ailleurs ou une couche de niveau inférieur dans votre application, demandez-vous si l'appelant souhaite détecter (connaître) votre exception.S'il ne l'est pas, utilisez une exception non vérifiée afin de ne pas le surcharger inutilement.

C'est la philosophie utilisée par de nombreux frameworks.Spring et hibernate, en particulier, me viennent à l'esprit - ils convertissent les exceptions vérifiées connues en exceptions non vérifiées précisément parce que les exceptions vérifiées sont surutilisées en Java.Un exemple auquel je peux penser est l'exception JSONException de json.org, qui est une exception vérifiée et qui est surtout ennuyeuse - elle devrait être décochée, mais le développeur n'y a tout simplement pas réfléchi.

D'ailleurs, la plupart du temps, l'intérêt de l'appelant pour l'exception est directement corrélé à la capacité de se remettre de l'exception, mais ce n'est pas toujours le cas.

Voici une solution très simple à votre dilemme Coché/Non coché.

Règle 1:Considérez une exception non vérifiée comme une condition testable avant l'exécution du code.Par exemple…

x.doSomething(); // the code throws a NullPointerException

où x est nul...…le code devrait éventuellement contenir ce qui suit…

if (x==null)
{
    //do something below to make sure when x.doSomething() is executed, it won’t throw a NullPointerException.
    x = new X();
}
x.doSomething();

Règle 2 :Considérez une exception vérifiée comme une condition non testable qui peut se produire pendant l'exécution du code.

Socket s = new Socket(“google.com”, 80);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();

…dans l'exemple ci-dessus, l'URL (google.com) peut être indisponible en raison d'une panne du serveur DNS.Même au moment où le serveur DNS fonctionnait et résolvait le nom « google.com » en adresse IP, si la connexion est établie à google.com, à tout moment par la suite, le réseau pourrait tomber en panne.Vous ne pouvez tout simplement pas tester le réseau tout le temps avant de lire et d'écrire sur des flux.

Il y a des moments où le code doit simplement s'exécuter avant que nous puissions savoir s'il y a un problème.En obligeant les développeurs à écrire leur code de manière à les obliger à gérer ces situations via Checked Exception, je dois tirer mon chapeau au créateur de Java qui a inventé ce concept.

En général, presque toutes les API Java suivent les 2 règles ci-dessus.Si vous essayez d'écrire dans un fichier, le disque risque de se remplir avant de terminer l'écriture.Il est possible que d'autres processus aient provoqué la saturation du disque.Il n'y a tout simplement aucun moyen de tester cette situation.Pour ceux qui interagissent avec du matériel dont l'utilisation peut échouer à tout moment, les exceptions vérifiées semblent être une solution élégante à ce problème.

Il y a une zone grise à ce sujet.Dans le cas où de nombreux tests sont nécessaires (une instruction if époustouflante avec beaucoup de && et ||), l'exception levée sera une CheckedException simplement parce que c'est trop pénible à résoudre - vous ne pouvez tout simplement pas dire ce problème est une erreur de programmation.S'il y a beaucoup moins de 10 tests (par ex.'if (x == null)'), alors l'erreur du programmeur doit être une UncheckedException.

Les choses deviennent intéressantes lorsqu’il s’agit d’interprètes linguistiques.Selon les règles ci-dessus, une erreur de syntaxe doit-elle être considérée comme une exception vérifiée ou non vérifiée ?Je dirais que si la syntaxe du langage peut être testée avant son exécution, il devrait s'agir d'une UncheckedException.Si le langage ne peut pas être testé (de la même manière que le code assembleur s'exécute sur un ordinateur personnel), l'erreur de syntaxe doit être une exception vérifiée.

Les 2 règles ci-dessus élimineront probablement 90 % de vos inquiétudes quant au choix.Pour résumer les règles, suivez ce modèle… 1) Si le code à exécuter peut être testé avant qu'il ne soit exécuté pour qu'il s'exécute correctement et si une exception se produit - akaune erreur du programmeur, l'exception doit être une UncheckedException (une sous-classe de RuntimeException).2) si le code à exécuter ne peut pas être testé avant d'être exécuté pour qu'il s'exécute correctement, l'exception doit être une exception vérifiée (une sous-classe d'exception).

Vous pouvez appeler cela une exception cochée ou non cochée ;cependant, les deux Les types d'exception peuvent être détectés par le programmeur, la meilleure réponse est donc :écrire tous de vos exceptions comme décoché et les documenter.De cette façon, le développeur qui utilise votre API peut choisir s'il souhaite intercepter cette exception et faire quelque chose.Les exceptions vérifiées sont une perte totale de temps pour tout le monde et font de votre code un cauchemar choquant à regarder.Des tests unitaires appropriés feront alors apparaître toutes les exceptions que vous devrez peut-être détecter et utiliser.

Exception vérifiée :Si le client peut récupérer d'une exception et souhaite continuer, utilisez l'exception vérifiée.

Exception non cochée :Si un client ne peut rien faire après l'exception, déclenchez une exception non contrôlée.

Exemple:Si vous devez effectuer une opération arithmétique dans une méthode A() et en fonction de la sortie de A(), vous devez effectuer une autre opération.Si la sortie de la méthode A() est nulle et que vous n'attendez pas pendant l'exécution, vous devez alors lancer une exception de pointeur Null qui est une exception d'exécution.

Référer ici

Je suis d'accord avec la préférence pour les exceptions non contrôlées en règle générale, en particulier lors de la conception d'une API.L'appelant peut toujours choisir d'intercepter une exception documentée et non vérifiée.Vous n’obligez tout simplement pas inutilement l’appelant à le faire.

Je trouve les exceptions vérifiées utiles au niveau inférieur, en tant que détail d'implémentation.Cela semble souvent être un meilleur flux de mécanisme de contrôle que de devoir gérer un « code retour » d’erreur spécifié.Cela peut parfois aider à voir l'impact d'une idée de changement de code de bas niveau également...déclarez une exception vérifiée en aval et voyez qui devrait s'ajuster.Ce dernier point ne s'applique pas s'il existe de nombreux génériques : attraper (Exception e) ou lève une exception ce qui n’est généralement pas très bien pensé de toute façon.

Voici mon opinion que j'ai après de nombreuses années d'expérience en développement :

  1. Exception vérifiée.Cela fait partie du cas d'utilisation métier ou du flux d'appels, cela fait partie de la logique d'application à laquelle nous nous attendons ou non.Par exemple, connexion rejetée, condition non satisfaite, etc.Nous devons le gérer et afficher le message correspondant à l'utilisateur avec des instructions sur ce qui s'est passé et que faire ensuite (réessayer plus tard, etc.).Je l'appelle généralement exception de post-traitement ou exception « utilisateur ».

  2. Exception non vérifiée.Cela fait partie d'une exception de programmation, d'une erreur dans la programmation du code logiciel (bug, défaut) et reflète la manière dont les programmeurs doivent utiliser l'API conformément à la documentation.Si un document lib/framework externe indique qu'il s'attend à obtenir des données dans une certaine plage et non nulles, car NPE ou IllegalArgumentException sera levée, le programmeur doit s'y attendre et utiliser l'API correctement conformément à la documentation.Sinon, l'exception sera levée.Je l'appelle généralement exception de pré-traitement ou exception de « validation ».

Par public cible.Parlons maintenant du public cible ou du groupe de personnes pour lequel les exceptions ont été conçues (selon mon avis) :

  1. Exception vérifiée.Le public cible est constitué d’utilisateurs/clients.
  2. Exception non vérifiée.Le public cible est constitué de développeurs.En d’autres termes, les exceptions non cochées sont conçues uniquement pour les développeurs.

Par phase du cycle de vie du développement d’applications.

  1. L'exception vérifiée est conçue pour exister pendant tout le cycle de vie de production en tant que mécanisme normal et attendu par lequel une application gère les cas exceptionnels.
  2. Les exceptions non cochées sont conçues pour exister uniquement pendant le cycle de vie de développement/test de l'application. Elles doivent toutes être corrigées pendant cette période et ne doivent pas être levées lorsqu'une application est déjà en cours d'exécution en production.

La raison pour laquelle les frameworks utilisent généralement des exceptions non contrôlées (Spring par exemple) est que le framework ne peut pas déterminer la logique métier de votre application, c'est aux développeurs de les détecter et de concevoir leur propre logique.

Les exceptions cochées sont utiles pour les cas récupérables dans lesquels vous souhaitez fournir des informations à l'appelant (c'est-à-direautorisations insuffisantes, fichier introuvable, etc.).

Les exceptions non contrôlées sont rarement utilisées, voire pas du tout, pour informer l'utilisateur ou le programmeur d'erreurs graves ou de conditions inattendues pendant l'exécution.Ne les lancez pas si vous écrivez du code ou des bibliothèques qui seront utilisées par d'autres, car ils ne s'attendent peut-être pas à ce que votre logiciel lève des exceptions non contrôlées puisque le compilateur ne force pas leur capture ou leur déclaration.

Chaque fois qu'une exception est moins probable, et que nous pouvons continuer même après l'avoir détectée, et que nous ne pouvons rien faire pour éviter cette exception, nous pouvons utiliser une exception vérifiée.

Chaque fois que nous voulons faire quelque chose de significatif lorsqu'une exception particulière se produit et lorsque cette exception est attendue mais pas certaine, nous pouvons alors utiliser une exception vérifiée.

Chaque fois qu'une exception navigue dans différentes couches, nous n'avons pas besoin de la détecter dans chaque couche, dans ce cas, nous pouvons utiliser une exception d'exécution ou une exception d'enveloppement comme exception non vérifiée.

L'exception d'exécution est utilisée lorsqu'une exception est la plus susceptible de se produire, qu'il n'y a aucun moyen d'aller plus loin et que rien ne peut être récupéré.Dans ce cas-ci, nous pouvons donc prendre des précautions par rapport à cette exception.EX:NUllPointerException, ArrayOutofBoundsException.Ces situations sont plus susceptibles de se produire.Dans ce scénario, nous pouvons prendre des précautions lors du codage pour éviter une telle exception.Sinon, nous devrons écrire des blocs try catch partout.

Des exceptions plus générales peuvent être faites. Non cochées, des exceptions moins générales sont cochées.

Je pense que nous pouvons réfléchir à des exceptions à plusieurs questions :

pourquoi une exception se produit-elle ?Que pouvons-nous faire quand cela arrive

par erreur, un bug. telle qu'une méthode d'objet nul est appelée.

String name = null;
... // some logics
System.out.print(name.length()); // name is still null here

Ce type d'exception devrait être corrigé lors du test.Sinon, cela interrompt la production et vous obtenez un bug très important qui doit être corrigé immédiatement.Ce type d'exceptions n'a pas besoin d'être vérifié.

par entrée externe, vous ne pouvez pas contrôler ou faire confiance à la sortie d’un service externe.

String name = ExternalService.getName(); // return null
System.out.print(name.length());    // name is null here

Ici, vous devrez peut-être vérifier si le nom est nul si vous souhaitez continuer lorsqu'il est nul, sinon vous pouvez le laisser tranquille et il s'arrêtera ici et donnera à l'appelant l'exception d'exécution.Ce type d'exceptions n'a pas besoin d'être vérifié.

par exception d'exécution provenant de l'extérieur, vous ne pouvez pas contrôler ou faire confiance au service externe.

Ici, vous devrez peut-être intercepter toutes les exceptions d'ExternalService si vous souhaitez continuer lorsque cela se produit, sinon vous pouvez le laisser tranquille et il s'arrêtera ici et donnera à l'appelant l'exception d'exécution.

par exception vérifiée de l'extérieur, vous ne pouvez pas contrôler ou faire confiance au service externe.

Ici, vous devrez peut-être intercepter toutes les exceptions d'ExternalService si vous souhaitez continuer lorsque cela se produit, sinon vous pouvez le laisser tranquille et il s'arrêtera ici et donnera à l'appelant l'exception d'exécution.

Dans ce cas, avons-nous besoin de savoir quel type d’exception s’est produit dans ExternalService ? Ça dépend:

  1. si vous pouvez gérer certains types d'exceptions, vous devez les intercepter et les traiter.Pour les autres, faites des bulles.

  2. si vous avez besoin d'un journal ou d'une réponse à l'utilisateur pour une exception spécifique, vous pouvez les récupérer.Pour les autres, faites des bulles.

Il faut distinguer ces deux types d'exception selon qu'il s'agit ou non d'une erreur du programmeur.

  • Si une erreur est une erreur du programmeur, il doit s'agir d'une exception non vérifiée. Par exemple:SQLException/IOException/NullPointerException.Ces exceptions sont des erreurs de programmation.Ils doivent être gérés par le programmeur.Alors que dans l'API JDBC, SQLEXception est vérifiée, dans le printemps JDBCTemplate, il s'agit d'une exception non cochée. Le programmeur ne s'inquiète pas de SQELLECTENCE, lors de l'utilisation du printemps.
  • Si une erreur n’est pas une erreur du programmeur et que la raison vient de l’extérieur, il doit s’agir d’une exception vérifiée. Par exemple:Si le fichier est supprimé ou que l'autorisation du fichier est modifiée par quelqu'un d'autre, il doit être récupéré.

FileNotFoundException est un bon exemple pour comprendre les différences subtiles.FileNotFoundException est levée si le fichier est introuvable.Il y a deux raisons à cette exception.Si le chemin du fichier est défini par le développeur ou pris par l'utilisateur final via l'interface graphique, il doit s'agir d'une exception non vérifiée.Si le fichier est supprimé par quelqu'un d'autre, il doit s'agir d'une exception vérifiée.

L’exception vérifiée peut être gérée de deux manières.Ceux-ci utilisent try-catch ou propagent l'exception.En cas de propagation d'exception, toutes les méthodes de la pile d'appels seront couplage étroit en raison de la gestion des exceptions.C'est pourquoi nous devons utiliser Checked Exception avec précaution.

Dans le cas où vous développez un système d'entreprise en couches, vous devez choisir une exception principalement non vérifiée à lancer, mais n'oubliez pas d'utiliser une exception vérifiée dans le cas où vous ne pouvez rien faire.

Je pense que lors de la déclaration d'une exception d'application, il devrait s'agir d'une exception non vérifiée, c'est-à-dire d'une sous-classe de RuntimeException.La raison est qu'il n'encombrera pas le code de l'application avec try-catch et lancera une déclaration sur la méthode.Si votre application utilise Java Api qui génère des exceptions vérifiées qui doivent de toute façon être gérées.Dans d’autres cas, l’application peut lever une exception non vérifiée.Si l'appelant de l'application doit toujours gérer une exception non vérifiée, cela peut être fait.

La règle que j'utilise est la suivante :n'utilisez jamais d'exceptions non vérifiées !(ou quand vous ne voyez aucun moyen de contourner ce problème)

Du point de vue du développeur utilisant votre bibliothèque ou de l'utilisateur final utilisant votre bibliothèque/application, c'est vraiment nul d'être confronté à une application qui plante en raison d'une exception non résolue.Et compter sur un fourre-tout ne sert à rien non plus.

De cette façon, l'utilisateur final peut toujours recevoir un message d'erreur, au lieu que l'application disparaisse complètement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top