2010-12-08 15 views
73

Donc, je pensais avoir une bonne compréhension 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 quand devrait une utilisation personne jette dans une déclaration de méthode Java comme suit:Quand utiliser throws dans une déclaration de méthode Java?

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

De la lecture des messages similaires, je crois que lancers francs est utilisé comme une sorte de déclaration que SomeException a pu être levée pendant l'exécution de la méthode.

Ma confusion vient de 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()); 
      } 
    }

est-il une raison que vous souhaitez utiliser un lancers francs dans cet exemple? Il semble que si vous faites simplement des exceptions de gestion d'exception de quelque chose comme une exception IOException, vous auriez simplement besoin du bloc try/catch et c'est tout.

Répondre

71

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 postez, le développeur aurait dû faire l'un ou l'autre, pas les deux.

Généralement, si vous ne faites rien à 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 quand il convient de lancer des exceptions est ici

When to throw an exception?

+1

Les exceptions non vérifiées doivent-elles également être déclarées dans la signature de la méthode avec un 'throw', ou est-ce pratique de n'utiliser que 'throws' pour les exceptions vérifiées? – Cody

2

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

1

Dans l'exemple que vous avez donné, la méthode ne lance jamais d'exception d'E/S, donc la déclaration est incorrecte (mais valide). Ma conjecture est que la méthode originale a jeté l'exception IOException, mais elle a ensuite été mise à jour pour gérer l'exception mais la déclaration n'a pas été modifiée.

18

Vous devez uniquement inclure une clause throws sur une méthode si la méthode renvoie une exception vérifiée. Si la méthode renvoie une exception d'exécution, il n'est pas nécessaire de le faire.

Voir ici pour quelques informations sur vérifié vs exceptions non vérifiées: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

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

7

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

  1. Intercepter l'exception et le manipuler; auquel cas le throws est non nécessaire.

  2. Enlever le try/catch; Dans ce cas, l'exception sera traitée par une méthode d'appel .

  3. Intercepter l'exception, peut-être effectuer une action, puis rethrow l'exception (et pas seulement le message)

1

Le code affiché est erroné, il doit lancer une exception si est d'attraper un particulier exception dans le but de gérer IOException mais de lancer des exceptions non 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()); 
    } 

}

0

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

permet de dire 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 "lancers francs" Exceptions, mais les lancers francs! L'astuce est que les exceptions levées sont RuntimeExceptions (non cochées) qui n'ont pas besoin d'être déclarées sur la méthode. Il est un peu trompeur pour le lecteur de la méthode, puisque tout ce qu'elle voit est un «lancer e»; déclaration, mais aucune déclaration de la throws Exception

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 la « lancers francs » exceptions dans la méthode sinon nous obtenons une erreur de compilation.