Maison >Java >javaDidacticiel >Amélioration Java (dix-sept) -----Exception (deux)

Amélioration Java (dix-sept) -----Exception (deux)

黄舟
黄舟original
2017-02-10 11:45:301062parcourir

Suite du billet de blog précédent : Chapitre sur l'amélioration de Java (16) -----Exception (1)

5. Exceptions personnalisées

 Java nous fournit de nombreuses exceptions, mais le système d'exceptions ne peut pas prévoir toutes les erreurs que nous souhaitons signaler, donc Java nous permet de personnaliser la représentation des exceptions. problèmes spécifiques qui peuvent être rencontrés dans le programme, en un mot : on n'est pas obligé de s'en tenir aux types d'exceptions existants en Java.

 L'utilisation des exceptions personnalisées Java nécessite les quatre étapes suivantes :

  1. Définissez une classe pour hériter de Throwable ou de sa sous-classe.

  2. Ajoutez une méthode de construction (bien sûr, vous pouvez également utiliser la méthode de construction par défaut sans ajouter il).

 3. Lancez cette exception dans une certaine classe de méthode.

  4. Attrapez l'exception.

/** 自定义异常 继承Exception类 **/
public class MyException extends Exception{
    public MyException(){
        
    }
    
    public MyException(String message){
        super(message);
    }
}

public class Test {
    public void display(int i) throws MyException{
        if(i == 0){
            throw new MyException("该值不能为0.......");
        }
        else{
            System.out.println( i / 2);
        }
    }
    
    public static void main(String[] args) {
        Test test = new Test();
        try {
            test.display(0);
            System.out.println("---------------------");
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}

       >Exécuter résultats :


La demande du client est transmise tout au long de cette chaîne jusqu'à sa réception et son traitement. De même, le mécanisme d'exception Java fournit également une telle chaîne : chaîne d'exceptions.

               

Nous savons que chaque fois que nous rencontrons un message d'exception, nous devons essayer... attraper, l'un d'entre eux va bien, que se passe-t-il si plusieurs exceptions se produisent ? Le traitement de la classification sera certainement plus gênant, utilisez donc une seule exception pour résoudre toutes les exceptions. Cela est effectivement possible, mais cette approche rendra inévitablement la maintenance ultérieure plus difficile. La meilleure façon est d'encapsuler ces informations d'exception, puis de capturer notre classe d'encapsulation.

Il est vrai que dans les applications, parfois nous devons non seulement encapsuler des exceptions, mais aussi les transmettre. Comment livrer ? jette! frénésie, c'est exact ! ! Mais si vous utilisez uniquement des lancers pour lancer des exceptions, que devez-vous faire de votre classe encapsulée ? ?

Nous avons deux façons de gérer les exceptions. La première consiste à les transmettre au supérieur pour traitement, et l'autre est d'essayer... catch effectue un traitement spécifique. Mais quel est le rapport avec ce qui précède ? Nous n'avons besoin d'effectuer aucun traitement dans le bloc catch de try...catch. Nous utilisons simplement le mot-clé throw pour lancer activement les informations d'exception que nous encapsulons. Continuez ensuite à lancer l'exception de méthode via le mot-clé throws. Sa couche supérieure peut également effectuer un tel traitement, et par analogie, une chaîne d'exceptions composée d'exceptions sera générée.

                                                     Maintenance et convivialité du système.

      同理,我们有时候在捕获一个异常后抛出另一个异常信息,并且希望将原始的异常信息也保持起来,这个时候也需要使用异常链。

      在异常链的使用中,throw抛出的是一个新的异常信息,这样势必会导致原有的异常信息丢失,如何保持?在Throwable及其子类中的构造器中都可以接受一个cause参数,该参数保存了原有的异常信息,通过getCause()就可以获取该原始异常信息。

      语法:

public void test() throws XxxException{
        try {
            //do something:可能抛出异常信息的代码块
        } catch (Exception e) {
            throw new XxxException(e);
        }
    }

      示例:

public class Test {
    public void f() throws MyException{
         try {
            FileReader reader = new FileReader("G:\\myfile\\struts.txt");  
             Scanner in = new Scanner(reader);  
             System.out.println(in.next());
        } catch (FileNotFoundException e) {
            //e 保存异常信息
            throw new MyException("文件没有找到--01",e);
        }  
    }
    
    public void g() throws MyException{
        try {
            f();
        } catch (MyException e) {
            //e 保存异常信息
            throw new MyException("文件没有找到--02",e);
        }
    }
    
    public static void main(String[] args) {
        Test t = new Test();
        try {
            t.g();
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}


      运行结果:

com.test9.MyException: 文件没有找到--02
    at com.test9.Test.g(Test.java:31)
    at com.test9.Test.main(Test.java:38)
Caused by: com.test9.MyException: 文件没有找到--01
    at com.test9.Test.f(Test.java:22)
    at com.test9.Test.g(Test.java:28)
    ... 1 more
Caused by: java.io.FileNotFoundException: G:\myfile\struts.txt (系统找不到指定的路径。)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:106)
    at java.io.FileInputStream.<init>(FileInputStream.java:66)
    at java.io.FileReader.<init>(FileReader.java:41)
    at com.test9.Test.f(Test.java:17)
    ... 2 more

      如果在程序中,去掉e,也就是:throw new MyException("文件没有找到--02");

      那么异常信息就保存不了,运行结果如下:

com.test9.MyException: 文件没有找到--02
    at com.test9.Test.g(Test.java:31)
    at com.test9.Test.main(Test.java:38)

      PS:其实对于异常链鄙人使用的也不是很多,理解的不是很清楚,望各位指正!!!!

       七、异常的使用误区

      首先我们先看如下示例:该实例能够反映java异常的不正确使用(其实这也是我刚刚学Java时写的代码)!!

OutputStreamWriter out = null;
        java.sql.Connection conn = null;
        try {            //   ---------1
            Statement stat = conn.createStatement();
            ResultSet rs = stat.executeQuery("select *from user");
            while (rs.next()){
                out.println("name:" + rs.getString("name") + "sex:"
                        + rs.getString("sex"));
            }
            conn.close();         //------2
            out.close();
        } 
        catch (Exception ex){    //------3
            ex.printStackTrace();    //------4
        }


      1、-----------1

      对于这个try…catch块,我想他的真正目的是捕获SQL的异常,但是这个try块是不是包含了太多的信息了。这是我们为了偷懒而养成的代码坏习惯。有些人喜欢将一大块的代码全部包含在一个try块里面,因为这样省事,反正有异常它就会抛出,而不愿意花时间来分析这个大代码块有那几块会产生异常,产生什么类型的异常,反正就是一篓子全部搞定。这就想我们出去旅游将所有的东西全部装进一个箱子里面,而不是分类来装,虽不知装进去容易,找出来难啊!!!所有对于一个异常块,我们应该仔细分清楚每块的抛出异常,因为一个大代码块有太多的地方会出现异常了。

      结论一:尽可能的减小try块!!!

      2、--------2

 Qu'avez-vous trouvé ici ? Les exceptions modifient le processus en cours ! ! Ce qui est bien, c’est que les exceptions modifient le déroulement du programme. Si une exception se produit dans le programme, il est impossible d'exécuter conn.close();out.close();, ce qui entraînera inévitablement la non-libération des ressources. Par conséquent, si le programme utilise des ressources telles que des fichiers, des Sockets et des connexions JDBC, même si une exception est rencontrée, nous devons nous assurer que les ressources occupées peuvent être libérées correctement. C'est ici qu'entre enfin en jeu : peu importe qu'une exception se produise ou non, il a toujours une chance de s'exécuter, il est donc parfait pour libérer des ressources.

 Conclusion 2 : Assurez-vous que toutes les ressources sont correctement libérées. Utilisez pleinement le mot-clé enfin.

 3. ----------3

 Pour ce code Je pense que la plupart des gens gèrent les choses de cette façon (LZ aussi). Les personnes qui utilisent un tel code ont la mentalité selon laquelle une seule capture peut résoudre toutes les exceptions. C'est possible, mais ce n'est pas recommandé ! Pourquoi! Tout d'abord, nous devons comprendre que le bloc catch représente le type d'exception auquel il s'attend et quel type de traitement doit être effectué. Utiliser Exception signifie qu'il doit gérer toutes les informations sur les exceptions, mais quelle est la signification de cette opération. donc?

                                                                                                             Deux informations d'exception, SQLException et IOException. Il est donc évidemment inapproprié qu’un seul catch gère deux exceptions complètement différentes. Ce serait bien mieux si vous utilisiez deux captures, une pour gérer SQLException et une pour gérer IOException. Donc :

 Conclusion 3 : l'instruction catch doit être aussi spécifique que possible, et ne doit pas spécifier une classe d'exception qui couvre une plage trop large. N'essayez pas de gérer toutes les exceptions possibles avec une seule exception.

 4, --- -------4

 C'est le problème Il y en a tellement, je peux garantir que presque tout le monde les a utilisés de cette façon. Il y a deux problèmes ici. L'un est que l'exception est interceptée mais n'est pas gérée, et l'autre est que les informations sur l'exception ne sont pas assez claires.

                                                                                                                                                                                 Nous savons tous que les exceptions signifient qu'un problème inattendu s'est produit dans le programme. Le programme espère que nous pourrons le gérer pour le sauvegarder, mais qu'en est-il de vous ? Une seule phrase de ex.printStackTrace() suffit. Comme il est irresponsable d'ignorer la situation anormale du programme. Bien que cela puisse être utile pendant le débogage, qu’en est-il une fois la phase de débogage terminée ? Tout ne peut pas être fait avec juste ex.printStackTrace() !  

Alors comment s'améliorer ? Il existe quatre options :  

1. Gérer les exceptions. Gérez les exceptions qui se produisent, comme la correction des erreurs et l'envoi de rappels. Encore une fois, ex.printStackTrace() ne compte pas comme "gestion de l'exception".

      2、重新抛出异常。既然你认为你没有能力处理该异常,那么你就尽情向上抛吧!!!

      3、封装异常。这是LZ认为最好的处理方法,对异常信息进行分类,然后进行封装处理。

      4、不要捕获异常。

      4.2、异常信息不明确。我想对于这样的:java.io.FileNotFoundException: ………信息除了我们IT人没有几个人看得懂和想看吧!所以在出现异常后,我们最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。起码我公司是需要将异常信息所在的类、方法、何种异常都需要记录在日志文件中的。

所以:

      结论四:既然捕获了异常,就要对它进行适当的处理。不要捕获异常之后又把它丢弃,不予理睬。 不要做一个不负责的人。

      结论五:在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。

      对于异常还有以下几个注意地方:

      六、不要在finally块中处理返回值。

      七、不要在构造函数中抛出异常。



       八、try…catch、throw、throws

      在这里主要是区分throw和throws。

      throws是方法抛出异常。在方法声明中,如果添加了throws子句,表示该方法即将抛出异常,异常的处理交由它的调用者,至于调用者任何处理则不是它的责任范围内的了。所以如果一个方法会有异常发生时,但是又不想处理或者没有能力处理,就使用throws吧!

      而throw是语句抛出异常。它不可以单独使用,要么与try…catch配套使用,要么与throws配套使用。

//使用throws抛出异常
    public void f() throws MyException{
         try {
            FileReader reader = new FileReader("G:\\myfile\\struts.txt");  
             Scanner in = new Scanner(reader);  
             System.out.println(in.next());
        } catch (FileNotFoundException e) {
            throw new MyException("文件没有找到", e);    //throw
        }  
        
    }




 9.Résumé

 En fait, il y a effectivement beaucoup de discussions sur les avantages et les inconvénients du recours aux exceptions. Par exemple : http://www.php.cn/. Cet article de blog propose une discussion plus approfondie sur l'opportunité d'utiliser des exceptions. LZ est vraiment une recrue et ne peut pas comprendre les choses extrêmement profondes. Mais une chose dont LZ peut être sûr, c'est que les anomalies affecteront certainement les performances du système.

Guide d'utilisation des exceptions (extrait de : Think in java)

Des exceptions doivent être utilisées dans les situations suivantes.

  1. Gérez le problème au niveau approprié (attrapez l'exception uniquement si vous savez comment gérer c'est anormal).

2. Résolvez le problème et rappelez la méthode qui a généré l'exception.

  3. Créez un petit patch, puis continuez l'exécution en contournant l'endroit où l'exception s'est produite.

  4. Utilisez d'autres données pour effectuer des calculs afin de remplacer la valeur attendue par la méthode.

  5. Essayez de faire tout ce qui peut être fait dans l'environnement opérationnel actuel. Ensuite, la même exception (différente) est renvoyée à un niveau supérieur.

  6. Terminez le programme.

  7. Simplifiez.

   8. Rendre les bibliothèques de classes et les programmes plus sécurisés. (C'est à la fois un investissement à court terme pour le débogage et un investissement à long terme pour la robustesse du programme)


Ce qui précède est le contenu du chapitre sur l'amélioration de Java (17) -----Exception (2) Pour plus de contenu connexe, veuillez). faites attention au site Web PHP chinois (www .php.cn) !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn