Différence entre les lancers et les lancers en Java

1. Introduction

Dans ce didacticiel, nous examinerons les lancers et les lancers en Java. Nous expliquerons quand nous devrions utiliser chacun d'eux.

Ensuite, nous montrerons quelques exemples de leur utilisation de base.

2. Jeter et Lancers

Commençons par une brève introduction. Ces mots-clés sont liés à la gestion des exceptions. Des exceptions sont levées lorsque le flux normal de notre application est perturbé.

Il peut y avoir de nombreuses raisons. Un utilisateur pourrait envoyer les mauvaises données d'entrée. Nous pouvons perdre une connexion ou une autre situation inattendue peut se produire. Une bonne gestion des exceptions est essentielle pour que notre application continue de fonctionner après l'apparition de ces moments désagréables.

Nous utilisons le mot clé throw pour lancer explicitement une exception à partir du code. Cela peut être n'importe quelle méthode ou bloc statique. Cette exception doit être une sous-classe de Throwable. En outre, il peut s'agir d'un jetable lui-même. Nous ne pouvons pas lancer plusieurs exceptions avec un seul lancer .

Le mot clé Throws peut être placé dans la déclaration de méthode. Il indique quelles exceptions peuvent être levées à partir de cette méthode. Nous devons gérer ces exceptions avec try-catch.

Ces deux mots-clés ne sont pas interchangeables!

3. Lancez Java

Jetons un coup d'œil à un exemple de base en lançant une exception de la méthode.

Tout d'abord, imaginez que nous écrivons une simple calculatrice. L'une des opérations arithmétiques de base est la division. Pour cette raison, il nous a été demandé de mettre en œuvre cette fonctionnalité:

public double divide(double a, double b) { return a / b; }

Parce que nous ne pouvons pas diviser par zéro, nous devons ajouter quelques modifications à notre code existant. Il semble que ce soit un bon moment pour lever une exception.

Faisons cela:

public double divide(double a, double b) { if (b == 0) { throw new ArithmeticException("Divider cannot be equal to zero!"); } return a / b; }

Comme vous pouvez le voir, nous avons utilisé ArithmeticException avec parfaitement adapté à nos besoins. Nous pouvons passer un seul paramètre de constructeur String qui est un message d'exception.

3.1. Bonnes pratiques

Nous devrions toujours préférer l'exception la plus spécifique. Nous devons trouver une classe qui correspond le mieux à notre événement exceptionnel. Par exemple, lancez NumberFormatException au lieu de IllegalArgumentException. Nous devrions éviter de lancer une exception non spécifique .

Par exemple, il existe une classe Integer dans le package java.lang . Jetons un coup d'œil à celle de la déclaration de méthode d'usine:

public static Integer valueOf(String s) throws NumberFormatException 

C'est une méthode de fabrique statique qui crée une instance Integer à partir de String. En cas de chaîne d' entrée incorrecte , la méthode lèvera NumberFormatException.

Une bonne idée est de définir notre propre exception, plus descriptive. Dans notre classe Calculator , cela pourrait être par exemple DivideByZeroException.

Jetons un coup d'œil à un exemple d'implémentation:

public class DivideByZeroException extends RuntimeException { public DivideByZeroException(String message) { super(message); } }

3.2. Envelopper une exception existante

Parfois, nous voulons intégrer une exception existante dans l'exception que nous avons définie.

Commençons par définir notre propre exception:

public class DataAcessException extends RuntimeException { public DataAcessException(String message, Throwable cause) { super(message, cause); } }

Le constructeur prend deux paramètres: un message d'exception et une cause, qui peut être n'importe quelle sous-classe de Throwable.

Écrivons une fausse implémentation pour la fonction findAll () :

public List findAll() throws SQLException { throw new SQLException(); }

Maintenant, dans SimpleService , appelons une fonction de référentiel, ce qui peut entraîner SQLException:

public void wrappingException() { try { personRepository.findAll(); } catch (SQLException e) { throw new DataAccessException("SQL Exception", e); } }

Nous relançons SQLException encapsulée dans notre propre exception appelée DataAccessException. Tout est vérifié par le test suivant:

@Test void whenSQLExceptionIsThrown_thenShouldBeRethrownWithWrappedException() { assertThrows(DataAccessException.class, () -> simpleService.wrappingException()); }

Il y a deux raisons de faire cela. Tout d'abord, nous utilisons l'encapsulation d'exceptions, car le reste du code n'a pas besoin de connaître toutes les exceptions possibles dans le système.

De même, les composants de niveau supérieur n'ont pas besoin de connaître les composants de niveau inférieur, ni les exceptions qu'ils lancent.

3.3. Multi-Catch avec Java

Parfois, les méthodes que nous utilisons peuvent lever de nombreuses exceptions différentes.

Jetons un coup d'œil à un bloc try-catch plus complet:

try { tryCatch.execute(); } catch (ConnectionException | SocketException ex) { System.out.println("IOException"); } catch (Exception ex) { System.out.println("General exception"); }

The execute method can throw three exceptions: SocketException, ConnectionException, Exception. The first catch block will catch ConnectionException or SocketException. The second catch block would catch Exception or any other subclass of Exception. Remember, that we should always catch a more detailed exception first.

We can swap the order of our catch blocks. Then, we'd never catch SocketException and ConnectionException because everything will go to the catch with Exception.

4. Throws in Java

We add throws to the method declaration.

Let's take a look at one of our previous method declaration:

public static void execute() throws SocketException, ConnectionException, Exception

The method may throw multiple exceptions. They are comma-separated at the end of a method declaration. We can put both, checked and unchecked exceptions in the throws. We have described the difference between them below.

4.1. Checked and Unchecked Exceptions

A checked exception means that it's checked at the compile time. Note, that we must handle this exception. Otherwise, a method must specify an exception by using throws keyword.

The most common checked exceptions are IOException, FileNotFoundException, ParseException. FileNotFoundException may be thrown when we create FileInputStream from File.

There's a short example:

File file = new File("not_existing_file.txt"); try { FileInputStream stream = new FileInputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); }

We can avoid using try-catch block by adding throws to the method declaration:

private static void uncheckedException() throws FileNotFoundException { File file = new File("not_existing_file.txt"); FileInputStream stream = new FileInputStream(file); }

Unfortunately, a higher level function still has to handle this exception. Otherwise, we have to put this exception in method declaration with throws keyword.

As the opposite, unchecked exceptions aren't checked at the compile time.

The most common unchecked exceptions are: ArrayIndexOutOfBoundsException, IllegalArgumentException, NullPointerException.

Unchecked exceptions are thrown during runtime. The following code will throw a NullPointerException. Probably it's one of the most common exceptions in Java.

Calling a method on a null reference will result in this exception:

public void runtimeNullPointerException() { String a = null; a.length(); }

Let's verify this behavior in the test:

@Test void whenCalled_thenNullPointerExceptionIsThrown() { assertThrows(NullPointerException.class, () -> simpleService.runtimeNullPointerException()); }

N'oubliez pas que ce code et ce test n'ont pas beaucoup de sens. C'est uniquement à des fins d'apprentissage pour expliquer les exceptions d'exécution.

En Java, chaque sous-classe de Error et RuntimeException est une exception non vérifiée . Une exception vérifiée est tout le reste sous la classe Throwable .

5. Conclusion

Dans cet article, nous avons discuté de la différence entre deux mots-clés Java: throw et throws. Nous avons passé en revue l'utilisation de base et parlé un peu des bonnes pratiques . Ensuite, nous avons parlé des exceptions vérifiées et non vérifiées.

Comme toujours, le code source peut être trouvé sur notre GitHub.

Si vous souhaitez approfondir la gestion des exceptions en Java, veuillez consulter notre article sur les exceptions Java.