Heim  >  Artikel  >  Java  >  Java-Verbesserung (siebzehn) ----- Ausnahme (zwei)

Java-Verbesserung (siebzehn) ----- Ausnahme (zwei)

黄舟
黄舟Original
2017-02-10 11:45:301032Durchsuche

Fortsetzung des vorherigen Blogbeitrags: Java-Verbesserungskapitel (16)-----Ausnahme (1)

5. Benutzerdefinierte Ausnahmen

 Java stellt uns zwar viele Ausnahmen zur Verfügung, aber das Ausnahmesystem kann nicht alle Fehler vorhersehen, die wir melden möchten, daher ermöglicht uns Java, Ausnahmen anzupassen stellt spezifische Probleme dar, die im Programm auftreten können. Mit einem Wort: Wir müssen uns nicht an die vorhandenen Ausnahmetypen in Java halten.

 Die Verwendung von benutzerdefinierten Java-Ausnahmen erfordert die folgenden vier Schritte:

  1. Definieren Sie eine Klasse, die Throwable oder seine Unterklasse erben soll.

  2. Fügen Sie eine Konstruktionsmethode hinzu (natürlich können Sie auch die Standardkonstruktionsmethode ohne Hinzufügen verwenden Es).

          3. Lösen Sie diese Ausnahme in einer bestimmten Methodenklasse aus.

  4. Fangen Sie die Ausnahme ab.

/** 自定义异常 继承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();
        }
    }
}

       >Ausführen Ergebnisse:


Die Anfrage des Kunden wird entlang dieser Kette weitergeleitet, bis sie empfangen und bearbeitet wird. In ähnlicher Weise bietet auch der Java-Ausnahmemechanismus eine solche Kette: Ausnahmekette.

               Eines ist in Ordnung. Was passiert, wenn mehrere Ausnahmen auftreten? Die Klassifizierungsverarbeitung wird definitiv schwieriger sein. Verwenden Sie daher eine Ausnahme, um alle Ausnahmen zu lösen. Dies ist zwar möglich, jedoch wird diese Vorgehensweise die spätere Wartung zwangsläufig erschweren. Der beste Weg besteht darin, diese Ausnahmeinformationen zu kapseln und dann unsere Kapselungsklasse zu erfassen.

Es stimmt, dass wir in Anwendungen manchmal Ausnahmen nicht nur kapseln müssen, sondern auch gib sie weiter. Wie liefern? wirft! Binge, richtig! ! Aber was sollten Sie mit Ihrer gekapselten Klasse tun, wenn Sie Throws nur zum Auslösen von Ausnahmen verwenden? ?

                                                           Aber was hat das mit dem oben Gesagten zu tun? Wir müssen im Catch-Block von try...catch keine Verarbeitung durchführen. Wir verwenden lediglich das Schlüsselwort throw, um die von uns gekapselten Ausnahmeinformationen aktiv auszulösen. Dann wird die Methodenausnahme weiterhin über das Schlüsselwort throws ausgelöst. Seine obere Schicht kann ebenfalls eine solche Verarbeitung durchführen, und analog dazu wird eine aus Ausnahmen bestehende Ausnahmekette generiert.

                                                    Wartbarkeit und Benutzerfreundlichkeit des Systems.

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

      在异常链的使用中,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

 Was hast du hier gefunden? Ausnahmen verändern den laufenden Prozess! ! Das Gute daran ist, dass Ausnahmen den Ablauf des Programms verändern. Wenn im Programm eine Ausnahme auftritt, kann conn.close();out.close(); nicht ausgeführt werden, was unweigerlich dazu führt, dass Ressourcen nicht freigegeben werden. Wenn das Programm daher Ressourcen wie Dateien, Sockets und JDBC-Verbindungen verwendet, müssen wir auch bei Auftreten einer Ausnahme sicherstellen, dass die belegten Ressourcen korrekt freigegeben werden können. Hier kommt endlich ins Spiel: Egal ob eine Ausnahme auftritt oder nicht, final hat immer eine Chance zur Ausführung und ist somit perfekt für die Freigabe von Ressourcen.

 Schlussfolgerung 2: Stellen Sie sicher, dass alle Ressourcen korrekt freigegeben werden. Nutzen Sie das Schlüsselwort „final“ voll aus.

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

 Für diesen Code Ich denke, die meisten Leute gehen so damit um (auch LZ). Leute, die solchen Code verwenden, haben die Mentalität, dass ein einziger Haken alle Ausnahmen lösen kann. Dies ist möglich, wird aber nicht empfohlen! Warum! Zunächst müssen wir verstehen, dass der Catch-Block darstellt, welche Art von Ausnahme er erwartet und welche Art von Verarbeitung durchgeführt werden muss. Die Verwendung von Exception bedeutet, dass er alle Ausnahmeinformationen verarbeiten muss, aber was bedeutet das? Also?

                                                                                                Zwei Ausnahmeinformationen, SQLException und IOException. Daher ist es offensichtlich unangemessen, dass ein Catch zwei völlig unterschiedliche Ausnahmen behandelt. Es wäre viel besser, wenn Sie zwei Catches verwenden würden, einen für die Behandlung von SQLException und einen für die Behandlung von IOException. Also:

 Schlussfolgerung 3: Die Catch-Anweisung sollte wie folgt lauten Der Ausnahmetyp sollte möglichst spezifisch sein und keine Ausnahmeklasse angeben, die einen zu großen Bereich abdeckt. Versuchen Sie nicht, alle möglichen Ausnahmen mit einer Ausnahme zu behandeln.

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

 Das ist das Problem Es gibt so viele, ich kann garantieren, dass fast jeder sie auf diese Weise verwendet hat. Hier gibt es zwei Probleme: Zum einen wird die Ausnahme abgefangen, aber nicht behandelt, und zum anderen sind die Ausnahmeinformationen nicht klar genug.

                                                                                                                                                                               Wir alle wissen, dass Ausnahmen bedeuten, dass im Programm ein unerwartetes Problem aufgetreten ist. Das Programm hofft, dass wir es beheben können, aber was ist mit Ihnen? Nur ein Satz ex.printStackTrace() reicht aus. Wie unverantwortlich es ist, die abnormale Situation des Programms zu ignorieren. Auch wenn dies beim Debuggen hilfreich sein kann, wie sieht es nach Abschluss der Debugging-Phase aus? Nicht alles kann nur mit ex.printStackTrace() erledigt werden!  

Wie kann man sich also verbessern? Es gibt vier Optionen:  

1. Ausnahmen behandeln. Behandeln Sie die auftretenden Ausnahmen, z. B. das Korrigieren von Fehlern und das Bereitstellen von Erinnerungen. Auch hier wird ex.printStackTrace() nicht als „die Ausnahme behandelt“ betrachtet.

      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. Zusammenfassung

 Tatsächlich wird viel über die Vor- und Nachteile der Verwendung von Ausnahmen diskutiert. Zum Beispiel: http://www.php.cn/. In diesem Blogbeitrag wird die Verwendung von Ausnahmen ausführlicher erläutert. LZ ist wirklich ein Neuling und kann die extrem tiefgründigen Dinge nicht verstehen. Aber eines ist sich LZ sicher: Ausnahmen werden sich definitiv auf die Leistung des Systems auswirken.

 Leitfaden zur Verwendung von Ausnahmen (Auszug aus: Think in Java)

Ausnahmen sollten in den folgenden Situationen verwendet werden.

  1. Behandeln Sie das Problem auf der entsprechenden Ebene (fangen Sie die Ausnahme nur ab, wenn Sie wissen, wie man damit umgeht es anormal).

2. Lösen Sie das Problem und rufen Sie die Methode erneut auf, die die Ausnahme generiert hat.

  3. Erstellen Sie einen kleinen Patch und fahren Sie dann mit der Ausführung fort, wobei Sie die Stelle umgehen, an der die Ausnahme aufgetreten ist.

  4. Verwenden Sie andere Daten, um Berechnungen durchzuführen und den Wert zu ersetzen, der voraussichtlich von der Methode zurückgegeben wird.

  5. Versuchen Sie, alles zu tun, was in der aktuellen Betriebsumgebung möglich ist. Dann wird dieselbe (andere) Ausnahme erneut auf eine höhere Ebene ausgelöst.

  6. Beenden Sie das Programm.

  7. Vereinfachen.

   8. Machen Sie Klassenbibliotheken und Programme sicherer. (Dies ist sowohl eine kurzfristige Investition für das Debuggen als auch eine langfristige Investition für die Robustheit des Programms)


Das Obige ist der Inhalt des Java-Verbesserungskapitels (17)-----Ausnahme (2) für weitere verwandte Inhalte Achten Sie auf die chinesische PHP-Website (www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn