Pourquoi éviter d'utiliser des exceptions pour contrôler votre flux en Java

Java est un langage de programmation universel qui propose de nombreuses solutions alternatives pour vos tâches spécifiques. Néanmoins, il existe de bonnes approches qui devraient être suivies, et il existe également certaines approches infructueuses que nous utilisons encore pour la plupart.

L'une des approches les plus courantes ayant échoué consiste à utiliser des exceptions pour contrôler le flux d'exécution. Cela devrait être évité pour deux raisons:

  1. Cela réduit les performances et la vitesse de votre code.
  2. Cela rend votre code moins lisible.

Commençons par regarder un exemple. Ici, l'exception est utilisée pour contrôler le flux d'exécution:

public static int findAge(String name) { try { String ageAsString = findUser(name); return ageAsString.length(); } catch (NameNotFoundException e) { return 0; } } private static String findUser(String name) { if(name==null) { throw new NameNotFoundException(); } return name; } 

Si l'utilisateur fournit une valeur non nulle pour le nom, la méthode findAge renverra la longueur de ce nom, mais si le nom d'utilisateur est nul, la méthode findUser lèvera une exception NameNotFoundException et dans ce cas, la méthode findAge renverra 0.

Comment pouvons-nous convertir ce code sans utiliser d'exceptions? En général, il existe de nombreuses options, envisagez l'une d'entre elles:

 public static int findAgeNoEx(String name) { String ageAsString = findUserNoEx(name); return ageAsString.length(); } private static String findUserNoEx(String name) { if(name==null) { return ""; } return name; } 

Afin de découvrir l'impact de l'exception sur les performances, j'ai préparé le code suivant qui appelle les deux variantes des méthodes 10 millions de fois: avec et sans exception.

 public class ControlFlowWithExceptionOrNot { public static class NameNotFoundException extends RuntimeException { private static final long serialVersionUID = 3L; } private static final int TRIAL = 10000000; public static void main(String[] args) throws InterruptedException { long start = System.currentTimeMillis(); for (int i = 0; i < TRIAL; i++) { findAgeNoEx(null); } System.out.println("Duration :" + (System.currentTimeMillis() - start)); long start2 = System.currentTimeMillis(); for (int i = 0; i < TRIAL; i++) { findAge(null); } System.out.println("Duration :" + (System.currentTimeMillis() - start2)); }; public static int findAge(String name) { try { String ageAsString = findUser(name); return ageAsString.length(); } catch (NameNotFoundException e) { return 0; } } private static String findUser(String name) { if (name == null) { throw new NameNotFoundException(); } return name; } public static int findAgeNoEx(String name) { String ageAsString = findUserNoEx(name); return ageAsString.length(); } private static String findUserNoEx(String name) { if (name == null) { return ""; } return name; } } 

Conclusion:

 Duration :16 Duration :6212 

Comme vous pouvez le voir, l'utilisation de l'exception nous a coûté des milliers de millisecondes sur mon Intel Core i7-3630QM.

Si nous comparons nos deux méthodes findAge en termes de lisibilité, la méthode sans exception est absolument claire: premièrement, nous pouvons être absolument sûrs que la méthode findUser renvoie une chaîne; et deuxièmement, quelle que soit la chaîne qui sera retournée, nous obtenons sa longueur. Dans le même temps, la méthode à l'exception est quelque peu déroutante: il n'est pas complètement clair ce que renvoie exactement la méthode findUser. Il peut renvoyer une chaîne ou lever une exception, ce qui n'est pas visible depuis la signature de la méthode. Pour cette raison, le paradigme de programmation fonctionnelle n'accepte pas l'utilisation d'exceptions.

En fin de compte, il serait préférable que vous utilisiez des exceptions lorsque l'exception survient vraiment et est nécessaire. Si vous utilisez des exceptions pour contrôler le flux d'exécution, cela entraînera une baisse des performances du programme et rendra votre code moins lisible.

J'espère que cet article vous a été intéressant et peut-être utile.

Source: https://habr.com/ru/post/fr476142/


All Articles