Pourquoi «throws Exception» est-il nécessaire lors de l'appel d'une fonction?

97
class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

Pourquoi les rapports compilateur que les méthodes show2(), show3()et main()ont

exception non signalée Exception qui doit être interceptée ou déclarée pour être levée

quand je supprime throws Exceptionde ces méthodes?

nr5
la source
2
@PaulTomblin main peut certainement être déclaré pour lancer Exception. Si tel est le cas, la JVM s'arrêtera. C'est aussi proche de l'ignorer que le compilateur le permet.
Taymon
Lorsque la méthode appelée ( Methdod1 ) est lancéeException , nous devons définir la méthode d'appel ( Method2 ) avec throws Exception; si nous ne remettons pas cette exception dans la méthode d'appel. Le but de ceci est d' indiquer à la méthode appelante ( Method3 ) de Method2 qu'une exception peut être levée par Method2 et que vous devez la gérer ici, sinon cela peut interrompre votre programme.
Rito du
De même, si Method3 ne gère pas l'exception dans son corps, il a dû définir throws Exceptiondans sa définition de méthode pour donner à heads up sa méthode d'appel. extension du commentaire précédent
Rito

Réponses:

144

En Java, comme vous le savez peut-être, les exceptions peuvent être classées en deux: une qui a besoin de la throwsclause ou doit être gérée si vous n'en spécifiez pas une et une autre qui n'en a pas. Maintenant, voyez la figure suivante:

entrez la description de l'image ici

En Java, vous pouvez lancer tout ce qui étend la Throwableclasse. Cependant, vous n'avez pas besoin de spécifier une throwsclause pour toutes les classes. Plus précisément, les classes qui sont soit un Errorou RuntimeExceptionou l' une des sous - classes de ces deux. Dans votre cas, ce Exceptionn'est pas une sous-classe d'un Errorou RuntimeException. Il s'agit donc d'une exception vérifiée et doit être spécifiée dans la throwsclause, si vous ne gérez pas cette exception particulière. C'est pourquoi vous aviez besoin de la throwsclause.


À partir du didacticiel Java :

Une exception est un événement, qui se produit pendant l'exécution d'un programme, qui perturbe le flux normal des instructions du programme.

Maintenant, comme vous le savez, les exceptions sont classées en deux: cochées et non cochées. Pourquoi ces classifications?

Exception vérifiée: ils sont utilisés pour représenter les problèmes qui peuvent être récupérés lors de l'exécution du programme. Ils ne sont généralement pas la faute du programmeur. Par exemple, un fichier spécifié par l'utilisateur n'est pas lisible, ou aucune connexion réseau disponible, etc., Dans tous ces cas, notre programme n'a pas besoin de quitter, à la place il peut prendre des actions comme alerter l'utilisateur, ou entrer dans une solution de secours mécanisme (comme le travail hors ligne lorsque le réseau n'est pas disponible), etc.

Exceptions non vérifiées: elles peuvent à nouveau être divisées en deux: les erreurs et les exceptions d'exécution. L'une des raisons pour lesquelles ils ne sont pas cochés est qu'ils sont nombreux et que leur traitement tous encombrera notre programme et réduira sa clarté. L'autre raison est:

  • Exceptions d'exécution: elles surviennent généralement en raison d'une erreur du programmeur. Par exemple, si une ArithmeticExceptiondivision par zéro se produit ou une ArrayIndexOutOfBoundsExceptionse produit, c'est parce que nous ne sommes pas assez prudents dans notre codage. Ils se produisent généralement à cause d'erreurs dans la logique de notre programme. Donc, ils doivent être effacés avant que notre programme entre en mode production. Ils ne sont pas contrôlés dans le sens où notre programme doit échouer lorsqu'il se produit, afin que nous, les programmeurs, puissions le résoudre au moment du développement et du test lui-même.

  • Erreurs: les erreurs sont des situations dont le programme ne peut généralement pas récupérer. Par exemple, si a StackOverflowErrorse produit, notre programme ne peut pas faire grand-chose, comme augmenter la taille de la pile d'appels de fonctions du programme. Ou si un OutOfMemoryErrorproblème survient, nous ne pouvons pas faire grand-chose pour augmenter la quantité de RAM disponible pour notre programme. Dans de tels cas, il est préférable de quitter le programme. C'est pourquoi ils ne sont pas contrôlés.

Pour des informations détaillées, voir:

Jomoos
la source
ce que j'ai obtenu de votre réponse, c'est que la classe Error et ses sous-classes et la classe RuntimeException et ses sous-classes, elles relèvent d'une exception non vérifiée (comme System.out.println (5/0); il n'est pas nécessaire de lancer car c'est un exception d'exécution, mais nous pouvons toujours appliquer try catch) et la classe Exception est vérifiée, nous devons donc déclarer la clause
throws
Encore une question: si les exceptions sont classées en non cochées et cochées, en particulier celles non cochées (erreurs d'exécution) pour éviter plus d'erreurs lors de la compilation?
nr5 le
@Jomoos - Dites que le code à l'intérieur d'une méthode lève IOException. Alors, est-il correct de mettre "throws Exception" dans la déclaration de la méthode?
MasterJoe
Oh. Je comprends maintenant. il y a une exception aux règles de la hiérarchie des exceptions. Fait du. Parfait. Sens. Merci Java.
JJS
25

Java nécessite que vous gériez ou déclariez toutes les exceptions. Si vous ne gérez pas une exception à l'aide d'un bloc try / catch, elle doit être déclarée dans la signature de la méthode.

Par exemple:

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

Doit être écrit comme suit:

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

De cette façon, vous pouvez vous débarrasser de la déclaration "throws Exception" dans la déclaration de méthode.

jebar8
la source
7
Toutes les exceptions qui ne sont pas des sous-classes de RuntimeException, c'est-à-dire.
yshavit
s'il y a une autre classe comme Exception qui est vérifiée?
nr5
1
Que voulez-vous dire? Puisque tous les objets d'exception ont "Exception" comme classe de base, si vous attrapez un objet "Exception" (comme dans mon exemple), il interceptera toute exception qui est levée. Pour être plus précis (puisque différentes exceptions nécessiteront probablement différentes manières de gérer les choses), vous devriez avoir plusieurs blocs catch.
jebar8
si je devais dire que les exceptions vérifiées doivent être gérées au moment de la compilation et interceptées au moment de l'exécution. Ai-je raison ? si oui, alors formuler la même phrase pour l'exception non cochée serait?
nr5
@ jebar8 - vous confondez Java avec .NET - en Java, les objets jetables doivent hériter Throwable(l'héritage Exceptionfonctionne aussi, car il s'étend Throwable, mais ce n'est pas obligatoire).
BrainSlugs83
4

Exceptionest une classe d'exception vérifiée. Par conséquent, tout code qui appelle une méthode qui déclare qu'elle throws Exceptiondoit la gérer ou la déclarer.

Taymon
la source
Chaque méthode de la chaîne est déclarée lancer Exception, y compris main. Alors, où est le problème?
Paul Tomblin
@PaulTomblin je demande que c'est pourquoi il est nécessaire d'écrire lève une exception dans les fonctions appelantes, appelant une fonction qui lève une exception
nr5
Ok, je n'ai pas compris pourquoi vous posiez des questions sur une erreur de compilation que vous n'obteniez pas réellement du code que vous avez posté. C'est une façon étrange de demander.
Paul Tomblin
4

La throws Exceptiondéclaration est un moyen automatisé de garder une trace des méthodes qui pourraient lever une exception pour des raisons anticipées mais inévitables. La déclaration est généralement spécifique sur le type ou les types d'exceptions qui peuvent être levées telles que throws IOExceptionou throws IOException, MyException.

Nous avons tous ou finirons par écrire du code qui s'arrête de manière inattendue et signale une exception due à quelque chose que nous n'avions pas anticipé avant d'exécuter le programme, comme la division par zéro ou l'index hors limites. Puisque les erreurs n'étaient pas attendues par la méthode, elles n'ont pas pu être "interceptées" et traitées avec une clause try catch. Les utilisateurs sans méfiance de la méthode ne seraient pas non plus au courant de cette possibilité et leurs programmes s'arrêteraient également.

Lorsque le programmeur sait que certains types d'erreurs peuvent se produire mais qu'il souhaite gérer ces exceptions en dehors de la méthode, la méthode peut «lancer» un ou plusieurs types d'exceptions à la méthode appelante au lieu de les gérer. Si le programmeur ne déclarait pas que la méthode (pourrait) lever une exception (ou si Java n'avait pas la capacité de la déclarer), le compilateur ne pouvait pas le savoir et il appartiendrait au futur utilisateur de la méthode de le savoir, attraper et gérer toutes les exceptions que la méthode peut lancer. Puisque les programmes peuvent avoir de nombreuses couches de méthodes écrites par de nombreux programmes différents, il devient difficile (impossible) de garder une trace des méthodes susceptibles de lever des exceptions.

Même si Java a la capacité de déclarer des exceptions, vous pouvez toujours écrire une nouvelle méthode avec des exceptions non gérées et non déclarées, et Java la compilera et vous pourrez l'exécuter et espérer le meilleur. Ce que Java ne vous laissera pas faire est de compiler votre nouvelle méthode si elle utilise une méthode qui a été déclarée comme une ou plusieurs exceptions, à moins que vous ne gériez la ou les exceptions déclarées dans votre méthode ou que vous déclariez votre méthode comme lançant la même chose exception (s) ou s'il y a plusieurs exceptions, vous pouvez en gérer certaines et lancer le reste.

Lorsqu'un programmeur déclare que la méthode lève un type d'exception spécifique, il s'agit simplement d'un moyen automatisé d'avertir les autres programmeurs utilisant la méthode qu'une exception est possible. Le programmeur peut alors décider de gérer l'exception ou de transmettre l'avertissement en déclarant que la méthode appelante lève également la même exception. Puisque le compilateur a été averti que l'exception est possible dans cette nouvelle méthode, il peut vérifier automatiquement si les futurs appelants de la nouvelle méthode gèrent l'exception ou la déclarent et imposent l'une ou l'autre.

La bonne chose à propos de ce type de solution est que lorsque le compilateur signale, Error: Unhandled exception type java.io.IOExceptionil donne le numéro de fichier et de ligne de la méthode qui a été déclarée pour lever l'exception. Vous pouvez alors choisir de simplement passer la responsabilité et déclarer votre méthode également "jette IOException". Cela peut être fait jusqu'à la méthode principale où cela provoquerait alors l'arrêt du programme et le rapport de l'exception à l'utilisateur. Cependant, il est préférable d'attraper l'exception et de la gérer d'une manière agréable, en expliquant à l'utilisateur ce qui s'est passé et comment y remédier. Lorsqu'une méthode intercepte et gère l'exception, elle n'a plus à déclarer l'exception. La responsabilité s'arrête là pour ainsi dire.

dansalmo
la source
0
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

Seuls de petits changements dans votre programme. Ce qui semble être mal compris par beaucoup concernant le problème principal, c'est que chaque fois que vous lancez une exception, vous devez la gérer, ce n'est pas nécessaire au même endroit (par exemple, la méthode show1,2,3 dans votre programme) mais vous devez au premier appelant la méthode à l'intérieur du «principal». en un mot, il y a 'throw', il doit y avoir 'catch / try', même si ce n'est pas la même méthode où l'exception se produit.

tawess
la source
0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

Comme il y a une exception vérifiée dans la méthode show (), qui n'est pas gérée dans cette méthode, nous utilisons le mot-clé throws pour propager l'exception.

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

Puisque vous utilisez la méthode show () dans la méthode show2 () et que vous avez propagé l'exception au moins, vous devriez gérer ici. Si vous ne gérez pas l'exception ici, vous utilisez le mot clé throws. C'est donc la raison pour laquelle vous utilisez le mot-clé throws à la signature de la méthode.

Aditya
la source
0

Si vous propagez l'exception en déclarant la directive throws dans la signature de la méthode actuelle, alors quelque part en haut de la ligne ou de la pile d'appels, une construction try / catch doit être utilisée pour gérer l'exception.

Beaumont Muni
la source
Ce commentaire doit être ajouté à la section des commentaires car il ne fournit pas de réponse vérifiable ou un exemple de réponse. - stackoverflow.com/help/how-to-answer
Paul Dawson
-1

Fondamentalement, si vous ne gérez pas l'exception au même endroit que vous la lancez, alors vous pouvez utiliser "throws exception" lors de la définition de la fonction.

Shahzeb Sheikh
la source