Quand utiliser des lancers dans une déclaration de méthode Java?


Je pensais donc avoir une bonne compréhension de base de la gestion des exceptions en Java, mais je lisais récemment du code qui me donnait une certaine confusion et des doutes. Mon principal doute que je veux aborder ici est quand une personne devrait-elle utiliser une déclaration de méthode Java comme celle-ci:

    public void method() throws SomeException
    {
         // method body here
    }

En lisant certains articles similaires, je comprends que throwsest utilisé comme une sorte de déclaration que SomeException pourrait être lancé pendant l'exécution de la méthode.

Mon la confusion vient d'un code qui ressemblait à ceci:

     public void method() throws IOException
     {
          try
          {
               BufferedReader br = new BufferedReader(new FileReader("file.txt"));
          }
          catch(IOException e)
          {
               System.out.println(e.getMessage());
          }
     }

Y a-t-il une raison pour laquelle vous voudriez utiliser un jette dans cet exemple? Il semble que si vous ne faites que gérer les exceptions de base de quelque chose comme une IOException, vous auriez simplement besoin du bloc try/catch et c'est tout.

Author: jbranchaud, 2010-12-09

7 answers

Si vous attrapez un type d'exception, vous n'avez pas besoin de le lancer, sauf si vous allez le relancer. Dans l'exemple que vous publiez, le développeur doit avoir fait l'un ou l'autre, pas les deux.

Typiquement, si vous n'allez rien faire à l'exception, vous ne devriez pas l'attraper.

La chose la plus dangereuse que vous puissiez faire est d'attraper une exception et de ne rien faire avec.

Une bonne discussion sur le moment où il est approprié de lancer des exceptions est ici

Quand lancer une exception?

 76
Author: hvgotcodes, 2017-05-23 12:10:11

Vous n'avez besoin d'inclure une clause throws sur une méthode que si la méthode lève une exception vérifiée. Si la méthode lève une exception d'exécution il n'est pas nécessaire de le faire.

Voir ici pour un arrière-plan sur les exceptions cochées vs non cochées: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Si la méthode intercepte l'exception et la traite en interne (comme dans votre deuxième exemple), alors il n'est pas nécessaire d'inclure une clause throws.

 19
Author: Shane Bell, 2010-12-08 21:32:08

Le code que vous avez regardé n'est pas idéal. Vous devriez soit:

  1. Attrapez l'exception et gérez-la; auquel cas le throws est unnecesary.

  2. Supprimer le try/catch; auquel cas l'exception sera gérée par un l'appel de la méthode.

  3. Attraper l'exception, éventuellement effectuez une action puis rethrow l'exception (pas seulement le message)

 9
Author: Damo, 2010-12-08 21:32:21

Vous avez raison, dans cet exemple, le throws est superflu. Il est possible qu'il ait été laissé là à partir d'une implémentation précédente - peut-être que l'exception a été initialement lancée au lieu d'être prise dans le bloc catch.

 2
Author: RevBingo, 2010-12-08 21:29:27

Dans l'exemple que vous avez donné, la méthode ne lancera jamais d'IOException, donc la déclaration est fausse (mais valide). Je suppose que la méthode d'origine a jeté l'IOException, mais elle a ensuite été mise à jour pour gérer l'exception à l'intérieur mais la déclaration n'a pas été modifiée.

 1
Author: DaveJohnston, 2010-12-08 21:31:28

Le code que vous avez posté est incorrect, il devrait lancer une exception s'il attrape une exception spécifique afin de gérer IOException mais de lancer des exceptions non attrapées.

Quelque Chose comme:

public void method() throws Exception{
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println(e.getMessage());
   }
}

Ou

public void method(){
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println("Catching IOException");
           System.out.println(e.getMessage());
   }catch(Exception e){
           System.out.println("Catching any other Exceptions like NullPontException, FileNotFoundExceptioon, etc.");
           System.out.println(e.getMessage());
   }

}

 1
Author: Ignacio lucatero, 2012-10-18 23:19:08

Ce n'est pas une réponse, mais un commentaire, mais je ne pouvais pas écrire un commentaire avec un code formaté, alors voici le commentaire.

Disons qu'il y a

public static void main(String[] args) {
  try {
    // do nothing or throw a RuntimeException
    throw new RuntimeException("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

La sortie est

test
Exception in thread "main" java.lang.RuntimeException: test
    at MyClass.main(MyClass.java:10)

Cette méthode ne déclare aucune exception "jette", mais les jette! L'astuce est que les exceptions levées sont des RuntimeExceptions (non cochées) qui ne doivent pas être déclarées sur la méthode. C'est un peu trompeur pour le lecteur de la méthode, car tout ce qu'elle voit est une déclaration " throw e;" mais aucune déclaration de l'exception throws

Maintenant, si nous avons

public static void main(String[] args) throws Exception {
  try {
    throw new Exception("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

Nous DEVONS déclarer les exceptions "throws" dans la méthode sinon nous obtenons une erreur du compilateur.

 1
Author: Αλέκος, 2017-11-30 15:51:38