国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java異常處理(Try Catch Finally)

Anshiii / 2099人閱讀

摘要:一前言異常處理大家都不陌生,總的來說有下面兩點拋出異常捕獲異常本文將在此基礎(chǔ)上,更加深入的談一些細(xì)節(jié)問題。

一 前言

java異常處理大家都不陌生,總的來說有下面兩點:

1.拋出異常:throw exception

class SimpleException{
    public void a() throws Exception{
        throw new Exception();
    };
}

2.捕獲異常:

public class MyException {
    public static void main(String[] args){
        MyException e = new MyException();
        SimpleException se = new SimpleException();
        try {
            se.a();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}

class SimpleException{
    public void a() throws Exception{
        throw new Exception();
    };
}

本文將在此基礎(chǔ)上,更加深入的談一些細(xì)節(jié)問題。

二 自定義異常類

java語言為我們提供了很多異常類,但是有時候我們?yōu)榱藢懘a的方便還是要自定義的去創(chuàng)造異常類:

class SimpleException extends Exception {};

創(chuàng)建好之后我們可以使用try catch捕獲它:

public class MyException {
    public static void main(String[] args){
        MyException e = new MyException();
        try {
            e.a();
        } catch (SimpleException e1) {
            e1.printStackTrace();
        }
    }
    
    public void a() throws SimpleException{
        throw new SimpleException();
    }
}

class SimpleException extends Exception {};

我們在MyException中定義了一個方法a(),讓它拋出SimpleException異常,然后我們在main()中調(diào)用這個方法,并使用try catch捕獲了這個異常:

SimpleException
    at MyException.a(MyException.java:15)
    at MyException.main(MyException.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Process finished with exit code 0

編譯執(zhí)行后的結(jié)果,主要看前三行就行了。這里著重說明幾點:
1.拋出異常類型的指定:(exception specification)
當(dāng)我們需要在一個方法中拋出一個異常時,我們使用throw后加某異常類的實例,程序會在此向客戶端程序(調(diào)用這段代碼的程序)拋出對應(yīng)異常并在此退出(相當(dāng)于return)。另外需要注意的是,我們必須在定義該方法的時候指明異常類型,比如下面這段代碼會拋出SimpleException異常

 public void a() throws SimpleException

2.拋出多個異常:

    public void a() throws SimpleException,AException,BException{
        throw new SimpleException();
        
    }

不同的異常類之間用逗號隔開即可,在這種情況下我們不必須throw每個異常類的實例(),但是客戶端代碼必須要catch到每個異常類:

public class MyException {
    public static void main(String[] args){
        MyException e = new MyException();
        try {
            e.a();
        } catch (SimpleException e1) {
            e1.printStackTrace();
        } catch (BException e1) {
            e1.printStackTrace();
        } catch (AException e1) {
            e1.printStackTrace();
        }
    }

    public void a() throws SimpleException,AException,BException{
        throw new SimpleException();
        
    }
}



class SimpleException extends Exception {};
class AException extends Exception{}
class BException extends Exception{}
三 stack trace

無論是拋出異常,或者是捕獲處理異常,我們的目的是為了寫出更健壯的程序,這很大程度上依賴于java異常機制給我們提供的異常信息,而它的載體就是stack trace。
前面的代碼中我們直接使用printStackTrace()打印出異常信息,其實我們還可以使用getStackTrace()方法來獲取StackTraceElement型的集合,如果你手頭有IDEA的話,你可以先搜索出StackTraceElement類,可以發(fā)現(xiàn)它實現(xiàn)了接口Serializable ,再看看它的類描述:

/**
 * An element in a stack trace, as returned by {@link
 * Throwable#getStackTrace()}.  Each element represents a single stack frame.
 * All stack frames except for the one at the top of the stack represent
 * a method invocation.  The frame at the top of the stack represents the
 * execution point at which the stack trace was generated.  Typically,
 * this is the point at which the throwable corresponding to the stack trace
 * was created.
 *
 * @since  1.4
 * @author Josh Bloch
 */

講的很清楚,這個類的每個實例都是stack trace的一個元素,代表著一個stack frame,stack trace是由getStackTrace()方法返回的。后邊的我試著翻譯了幾遍,都覺得不好,還是直接上代碼才能說清楚:

public class MyException {
    public static void main(String[] args){
        MyException e = new MyException();
        e.a();

    public void a(){
        try {
            throw new Exception();
        } catch (Exception e) {
            StackTraceElement[] ste = e.getStackTrace();
            System.out.println(ste.length);

        }
    }
}

我們定義了方法a,讓它拋出Exception異常的同時捕獲它,然后我們通過getStackTrace()方法得到一個StackTraceElement型的數(shù)組,并打印出數(shù)組的長度:

7

Process finished with exit code 0

我們把代碼稍微改一下,不在a中捕獲異常了,我們重新定義一個方法b,讓它在調(diào)用a的同時將異常捕獲:

public class MyException {
    public static void main(String[] args){
        MyException e = new MyException();
        e.b();
    }

    public void b(){
        try {
            a();
        } catch (Exception e) {
            StackTraceElement[] ste = e.getStackTrace();
            System.out.println(ste.length);
        }
    }

    public void a() throws Exception{
        throw new Exception();
    }
}

結(jié)果如下:

8

Process finished with exit code 0

別急,我們再來看點有趣的:

public class MyException {
    public static void main(String[] args){
        MyException exception = new MyException();
        try {
            exception.c();
        } catch (Exception e) {
            StackTraceElement[] ste = e.getStackTrace();
            System.out.println(ste.length);
            System.out.println("---------------------------------------------------------------");
            for (StackTraceElement s : e.getStackTrace()){
                System.out.println(s.getClassName()+":method "+s.getMethodName()+" at line"+s.getLineNumber());
            }
            System.out.println("---------------------------------------------------------------");

        }

    }

 public void c() throws Exception{
        try {
            a();
        }catch (Exception e){
            throw e;
        }
    }

    public void a() throws Exception{
        throw new Exception();
    }
}

下面是結(jié)果:

8
---------------------------------------------------------------
MyException:method a at line43
MyException:method c at line39
MyException:method main at line9
sun.reflect.NativeMethodAccessorImpl:method invoke0 at line-2
sun.reflect.NativeMethodAccessorImpl:method invoke at line57
sun.reflect.DelegatingMethodAccessorImpl:method invoke at line43
java.lang.reflect.Method:method invoke at line606
com.intellij.rt.execution.application.AppMain:method main at line144
---------------------------------------------------------------

Process finished with exit code 0

也就是說,getStackTrace()返回一個棧,它包含從調(diào)用者(main())到初始拋出異常者(a())的一些基本信息 ,在上面的代碼中,我們在c方法中調(diào)用a方法時捕獲異常并通過throws將其再次拋出(rethrow),調(diào)用c方法的方法可以捕獲并處理異常,也可以選擇繼續(xù)拋出讓更高層次的調(diào)用者(靠近棧底)處理。rethrow雖然很方便,但存在著一些問題,我們看下面這段代碼:

public class MyException {
    public static void main(String[] args){
        MyException exception = new MyException();
        try {
            exception.c();
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }

    }

    public void c() throws Exception{
        try {
            a();
        }catch (Exception e){
            throw e;
        }
    }

    public void a() throws Exception{

        throw new Exception("Exception from a()");
    }
}
java.lang.Exception: Exception from a()
    at MyException.a(MyException.java:40)
    at MyException.c(MyException.java:30)
    at MyException.main(MyException.java:21)

我們在c中重新拋出e,在main中使用 e.printStackTrace()打印出來,可以看到打印出來stack trace還是屬于a的,如果我們想把stack trace變成c的可以這么寫:

public class MyException {
    public static void main(String[] args){
        MyException exception = new MyException();

        try {
            exception.c();
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }

    }

    public void c() throws Exception{
        try {
            a();
        }catch (Exception e){
//            throw e;
            throw (Exception)e.fillInStackTrace();
        }
    }

    public void a() throws Exception{

        throw new Exception("Exception from a()");
    }
}
java.lang.Exception: Exception from a()
    at MyException.c(MyException.java:22)
    at MyException.main(MyException.java:10)
四 異常鏈 Exception chaining

先來看一個場景:

public class TestException {
    public static void main(String[] args){
        TestException testException = new TestException();
        try {
            testException.c();
        } catch (CException e) {
            e.printStackTrace();
        }
    }

    public void a() throws AException{
        AException aException = new AException("this is a exception");
        throw  aException;
    }

    public void b() throws BException{
        try {
            a();
        } catch (AException e) {
            throw new BException("this is b exception");
        }
    }

    public void c() throws CException{
        try {
            b();
        } catch (BException e) {
            throw new CException("this is c exception");
        }
    }
}

class AException extends Exception{
    public AException(String msg){
        super(msg);
    }
}

class BException extends Exception{
    public BException(String msg){
        super(msg);
    }
}

class CException extends Exception{
    public CException(String msg){
        super(msg);
    }
}

創(chuàng)建了三個異常類AException、BException、CException,然后在a()中拋出AException,在b()中捕獲AException并拋出BException,最后在c()中捕獲BException并拋出CException,結(jié)果打印如下:

CException: this is c exception
    at TestException.c(TestException.java:31)
    at TestException.main(TestException.java:8)

好,我們只看到了CException的信息,AException,BException的異常信息已丟失,這時候異常鏈的作用就出來了,看代碼:

public class TestException {
    public static void main(String[] args){
        TestException testException = new TestException();
        try {
            testException.c();
        } catch (CException e) {
            e.printStackTrace();
        }
    }

    public void a() throws AException{
        AException aException = new AException("this is a exception");
        throw  aException;
    }

    public void b() throws BException{
        try {
            a();
        } catch (AException e) {
//            throw new BException("this is b exception");
            BException bException = new BException("this is b exception");
            bException.initCause(e);
            throw bException;
        }
    }

    public void c() throws CException{
        try {
            b();
        } catch (BException e) {
//            throw new CException("this is c exception");
            CException cException = new CException("this is c exception");
            cException.initCause(e);
            throw cException;
        }
    }
}

class AException extends Exception{
    public AException(String msg){
        super(msg);
    }
}

class BException extends Exception{
    public BException(String msg){
        super(msg);
    }
}

class CException extends Exception{
    public CException(String msg){
        super(msg);
    }
}

我們用initCause()方法將異常信息給串聯(lián)了起來,結(jié)果如下:

CException: this is c exception
    at TestException.c(TestException.java:35)
    at TestException.main(TestException.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: BException: this is b exception
    at TestException.b(TestException.java:24)
    at TestException.c(TestException.java:32)
    ... 6 more
Caused by: AException: this is a exception
    at TestException.a(TestException.java:15)
    at TestException.b(TestException.java:21)
    ... 7 more

Process finished with exit code 0
五 后記

其實關(guān)于java異常處理還有很多需要探討的地方,但是由于我經(jīng)驗有限,還不能體會的太深刻,最常用的也就是

try {
            ...
        }catch (Exception e){
           ... 
        }finally {
          //不管異常會不會被捕捉或者處理都會執(zhí)行的代碼,如關(guān)閉IO操作 
        }

但是無論如何我們還是要感謝java給我們提供的異常機制,它好似一個長者,時不時給我們指引道路,也讓我們在編碼的時候沒有那么無聊:)

我的微信號是aristark,歡迎交流指正!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/66200.html

相關(guān)文章

  • “崩潰了?不可能,我全 Catch 住了” | Java 異常處理

    摘要:允許存在多個,用于針對不同的異常做不同的處理。表示程序可能需要捕獲并且處理的異常。因此,我們應(yīng)該盡可能的避免通過異常來處理正常的邏輯檢查,這樣可以確保不會因為發(fā)生異常而導(dǎo)致性能問題。異常表中的每一條記錄,都代表了一個異常處理器。 showImg(https://segmentfault.com/img/remote/1460000017918154?w=640&h=100); show...

    stdying 評論0 收藏0
  • Java? 教程(捕獲和處理異常

    捕獲和處理異常 本節(jié)描述如何使用三個異常處理程序組件 — try、catch和finally塊 — 來編寫異常處理程序,然后,解釋了Java SE 7中引入的try-with-resources語句,try-with-resources語句特別適用于使用Closeable資源的情況,例如流。 本節(jié)的最后一部分將介紹一個示例,并分析各種場景中發(fā)生的情況。 以下示例定義并實現(xiàn)名為ListOfNumbe...

    Yujiaao 評論0 收藏0
  • 異常機制詳解

    摘要:當(dāng)運行時系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器,則運行時系統(tǒng)終止。不可查異常編譯器不要求強制處置的異常包括運行時異常與其子類和錯誤。 目錄介紹 1.什么是異常 2.異常 2.1 異常的概述和分類【了解】 2.2 JVM默認(rèn)是如何處理異常的【理解】 2.3 異常處理的兩種方式【理解】 2.4 try...catch的方式處理異常【掌握】 2.5 編譯期異常和運行期異常的區(qū)別【理解】...

    wanghui 評論0 收藏0
  • java異常處理機制的理解

    摘要:根據(jù)異常對象判斷是否存在異常處理。否則,范圍小的異常會因異常處理完成而無法處理。異常處理中使用作為異常的統(tǒng)一出口。 參考《第一行代碼java》《java程序設(shè)計教程》java中程序的錯誤有語法錯誤、語義錯誤。如果是語法性錯誤,在編譯時就可以檢查出來并解決。語義錯誤是在程序運行時出現(xiàn)的,在編譯時沒有錯誤,但在運行時可能會出現(xiàn)錯誤導(dǎo)致程序退出,這些錯誤稱為異常。在沒有異常處理的情況下,也即...

    khs1994 評論0 收藏0
  • Java 異常處理

    摘要:下面是異常處理機制的語法結(jié)構(gòu)業(yè)務(wù)實現(xiàn)代碼輸入不合法如果執(zhí)行塊里業(yè)務(wù)邏輯代碼時出現(xiàn)異常,系統(tǒng)自動生成一個異常對象,該對象被提交給運行時環(huán)境,這個過程被稱為拋出異常。 Java的異常機制主要依賴于try、catch、finally、throw和throws五個關(guān)鍵字, try關(guān)鍵字后緊跟一個花括號括起來的代碼塊(花括號不可省略),簡稱try塊,它里面放置可能引發(fā)異常的代碼 catch后對...

    senntyou 評論0 收藏0
  • 究竟什么是Java異常

    摘要:例如將型對象轉(zhuǎn)換為類拋出的異常表明向方法傳遞了一個不合法或不正確的參數(shù)。應(yīng)用程序可以將此類子類化以指示類似的異常。用非法索引訪問數(shù)組時拋出的異常。 第四階段 IO 異常處理 沒有完美的程序,所以我們需要不斷地完善,考慮各種可能性,我們要將除了自己以外的任何用戶或者操作者都當(dāng)成傻子來考慮問題在我們開發(fā)過程中 我們運行時常常會遇到 這樣java.lang.XxxException的信息,這...

    DevTalking 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<