web-dev-qa-db-fra.com

Quand utiliser les jets dans une déclaration de méthode Java?

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

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

En lisant des articles similaires, je suppose que jette est utilisé comme une sorte de déclaration que SomeException pourrait être levée lors de l'exécution de la méthode.

Ma 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 d'une chose telle qu'une exception IOException, vous aurez simplement besoin du bloc try/catch et c'est tout.

79
jbranchaud

Si vous attrapez un type d'exception, vous n'avez pas besoin de le lancer, à moins que vous ne le rediffusiez. Dans l'exemple que vous publiez, le développeur aurait dû utiliser l'une ou l'autre, pas les deux.

En règle générale, si vous ne faites rien excepté, 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 opportun pour lancer des exceptions est ici

Quand lancer une exception?

77
hvgotcodes

Vous devez uniquement inclure une clause throws sur une méthode si celle-ci 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 quelques informations sur les exceptions vérifiées et non vérifié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), il n'est pas nécessaire d'inclure une clause throws.

20
Shane Bell

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

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

  2. Supprimez le try/catch; auquel cas l'exception sera gérée par une méthode d'appel

  3. Attrapez l'exception, éventuellement Exécutez une action, puis renvoyez l'exception

9
Damo

Vous avez raison, dans cet exemple, la variable throws est superflue. Il est possible que cela ait été laissé par 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
RevBingo

Ce n'est pas une réponse, mais un commentaire, mais je ne pouvais pas écrire de commentaire avec un code formaté, donc 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 pas d’exception "jette", mais les jette! Le truc, c’est que les exceptions levées sont des RuntimeExceptions (non cochées) qu’il n’est pas nécessaire de déclarer sur la méthode . le lecteur de la méthode, car tout ce qu'elle voit est un "lancer e"; déclaration mais pas de déclaration de l'exception des lancers

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 nous engageons à déclarer les exceptions "Throws" dans la méthode, sinon nous obtenons une erreur de compilation.

1
Αλέκος

Le code que vous avez posté est incorrect, il devrait lancer une exception s'il intercepte une exception spécifique afin de gérer IOException mais ne lance pas d'exceptions intercepté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
Ignacio lucatero

Dans l'exemple que vous avez donné, la méthode ne lève jamais une exception IOException, donc la déclaration est fausse (mais valide). À mon avis, la méthode d'origine renvoyait 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
DaveJohnston