<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    從制造到創(chuàng)造
    軟件工程師成長之路
    posts - 292,  comments - 96,  trackbacks - 0

    9.1 Java異常處理機(jī)制概述

    主要考慮的兩個(gè)問題:(1)如何表示異常情況?(2)如何控制處理異常的流程?

    9.1.1 Java異常處理機(jī)制的優(yōu)點(diǎn)

    Java語言按照面向?qū)ο蟮乃枷雭硖幚懋惓#沟贸绦蚓哂懈玫目删S護(hù)性。

    Java異常處理機(jī)制具有以下優(yōu)點(diǎn):
    • 把各種不同類型的異常情況進(jìn)行分類,用Java類來表示異常情況,發(fā)揮類的可擴(kuò)展性和可重用性。
    • 異常流程的代碼和正常流程的代碼分離,提供了程序的可讀性,簡化了程序的結(jié)構(gòu)。
    • 可以靈活地處理異常,如果當(dāng)前方法有能力處理異常,就捕獲并處理它,否則只需要拋出異常,由方法調(diào)用者來處理它。

    9.1.2 Java虛擬機(jī)的方法調(diào)用棧

    如果方法中的代碼塊可能拋出異常,有如下兩種處理方法:
    (1)在當(dāng)前方法中通過try...catch語句捕獲并處理異常;
    (2)在方法的聲明處通過throws語句聲明拋出異常。
    當(dāng)Java虛擬機(jī)追溯到調(diào)用棧的底部的方法時(shí),如果仍然沒有找到處理該異常的代碼,將按以下步驟處理:
    (1)調(diào)用異常對象的printStachTrace()方法,打印來自方法調(diào)用棧的異常信息。
    (2)如果該線程不是主線程,那么終止這個(gè)線程,其它線程繼續(xù)正常運(yùn)行。如果該線程是主線程,那么整個(gè)應(yīng)用程序被終止。

    9.1.3 異常處理對性能的影響

    一般來說,影響很小,除非方法嵌套調(diào)用很深。

    9.2 運(yùn)用Java異常處理機(jī)制

    9.2.1 try...catch語句:捕獲異常

    9.2.2 finally語句:任何情況下都必須執(zhí)行的代碼

    主要用于關(guān)閉某些流和數(shù)據(jù)庫連接。

    9.2.3 thorws子句:聲明可能會(huì)出現(xiàn)的異常

    9.2.4 throw語句:拋出異常

    9.2.5 異常處理語句的語法規(guī)則

    (1)try代碼塊不能脫離catch代碼塊或finally代碼塊而單獨(dú)存在。try代碼塊后面至少有一個(gè)catch代碼塊或finally代碼塊。
    (2)try代碼塊后面可以有零個(gè)或多個(gè)catch代碼塊,還可以有零個(gè)或至多一個(gè)finally代碼塊。
    (3)try代碼塊后面可以只跟finally代碼塊。
    (4)在try代碼塊中定義的變量的作用域?yàn)閠ry代碼塊,在catch代碼塊和finally代碼塊中不能訪問該變量。
    (5)當(dāng)try代碼塊后面有多個(gè)catch代碼塊時(shí),Java虛擬機(jī)會(huì)把實(shí)際拋出的異常類對象依次和各個(gè)catch代碼塊聲明的異常類型匹配,如果異常對象為某個(gè)異常類型或其子類的實(shí)例,就執(zhí)行這個(gè)catch代碼塊,而不會(huì)再執(zhí)行其他的catch代碼塊。
    (6)如果一個(gè)方法可能出現(xiàn)受檢查異常,要么用try...catch語句捕獲,要么用throws子句聲明將它拋出,否則會(huì)導(dǎo)致編譯錯(cuò)誤。

    9.2.6 異常流程的運(yùn)行過程

    (1)finally語句不被執(zhí)行的唯一情況是先執(zhí)行了用于終止程序的System.exit()方法。
    (2)return語句用于退出本方法。
    (3)finally代碼塊雖然在return語句之前被執(zhí)行,但finally代碼塊不能通過重新給變量賦值來改變r(jià)eturn語句的返回值。
    (4)建議不要在finally代碼塊中使用return語句,因?yàn)樗鼤?huì)導(dǎo)致以下兩種潛在的錯(cuò)誤
             A:覆蓋try或catch代碼塊的return語句
    public class SpecialException extends Exception {
        
    public SpecialException() {

        }

        
    public SpecialException(String msg) {
            
    super(msg);
        }
    }

    public class FinallyReturn {

        
    /**
         * 
    @param args
         
    */
        
    public static void main(String[] args) {
            FinallyReturn fr 
    = new FinallyReturn();
            System.out.println(fr.methodB(
    1));// 打印100
            System.out.println(fr.methodB(2));// 打印100
        }

        
    public int methodA(int money) throws SpecialException {
            
    if (--money <= 0) {
                
    throw new SpecialException("Out of money");
            }

            
    return money;
        }

        @SuppressWarnings(
    "finally")
        
    public int methodB(int money) {
            
    try {
                
    return methodA(money);// 可能拋出異常
            } catch (SpecialException e) {
                
    return -100;
            } 
    finally {
                
    return 100;// 會(huì)覆蓋try和catch代碼塊的return語句
            }
        }

    }

            B:丟失異常
    public class ExLoss {

        
    /**
         * 
    @param args
         
    */
        
    public static void main(String[] args) {
            
    try {
                System.out.println(
    new ExLoss().methodB(1));// 打印100
                System.out.println("No Exception");
            } 
    catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }

        
    public int methodA(int money) throws SpecialException {
            
    if (--money <= 0) {
                
    throw new SpecialException("Out of money");
            }

            
    return money;
        }

        @SuppressWarnings(
    "finally")
        
    public int methodB(int money) {
            
    try {
                
    return methodA(money);// 可能拋出異常
            } catch (SpecialException e) {
                
    throw new Exception("Wrong");
            } 
    finally {
                
    return 100;// 會(huì)丟失catch代碼塊中的異常
            }
        }
    }

    9.3 Java異常類

    所有異常類的祖先類為java.lang.Throwable類,它的實(shí)例表示具體的異常對象,可以通過throw語句拋出。

    Throwable類提供了訪問異常信息的一些方法,常用的方法包括:
    • getMessage() --返回String類型的異常信息。
    • printStachTrace()--打印跟蹤方法調(diào)用棧而獲得的詳細(xì)異常信息。在程序調(diào)試階段,此方法可用于跟蹤錯(cuò)誤。
    public class ExTrace {

        
    /**
         * 
    @param args
         
    */
        
    public static void main(String[] args) {
            
    try {
                
    new ExTrace().methodB(1);
            } 
    catch (Exception e) {
                System.out.println(
    "--- Output of main() ---");
                e.printStackTrace();
            }
        }

        
    public void methodA(int money) throws SpecialException {
            
    if (--money <= 0) {
                
    throw new SpecialException("Out of money");
            }
        }

        
    public void methodB(int money) throws Exception {
            
    try {
                methodA(money);    
            } 
    catch (SpecialException e) {
                System.out.println(
    "--- Output of methodB() ---");
                System.out.println(e.getMessage());
                
    throw new Exception("Wrong");
            }
        }
    }

    打印結(jié)果:
    --- Output of methodB() ---
    Out of money
    --- Output of main() ---
    java.lang.Exception: Wrong
        at chapter09.d0903.ExTrace.methodB(ExTrace.java:
    45)
        at chapter09.d0903.ExTrace.main(ExTrace.java:
    26)

    Throwable類有兩個(gè)直接子類:
    • Error類--表示僅靠程序本身無法恢復(fù)的嚴(yán)重錯(cuò)誤,如內(nèi)存不足等。
    • Exception類--表示程序本身可以處理的異常。

    9.3.1 運(yùn)行時(shí)異常

    RuntimeException類及其子類都被稱為運(yùn)行時(shí)異常,這種異常的特點(diǎn)是Java編譯器不會(huì)檢查它,會(huì)編譯通過,但運(yùn)行時(shí)如果條件成立就會(huì)出現(xiàn)異常。

    例如當(dāng)以下divided()方法的參數(shù)b為0,執(zhí)行“a/b”操作時(shí)會(huì)出現(xiàn)ArrithmeticException異常,它屬于運(yùn)行時(shí)異常,Java編譯器不會(huì)檢查它。

        public int divide2(int a, int b) {
            
    return a / b;// 當(dāng)參數(shù)為0,拋出ArrithmeticException
        }
    下面的程序中的IllegalArgumentException也是運(yùn)行時(shí)異常,divided()方法即沒有捕獲它,也沒有聲明拋出它。
    public class WithRuntimeEx {

        
    /**
         * @param args
         
    */
        
    public static void main(String[] args) {
            new WithRuntimeEx().divide(
    10);
            System.out.println("
    End");
        }

        
    public int divide(int a, int b) {
            
    if (b == 0) {
                throw new IllegalArgumentException("除數(shù)不能為0");
            }

            
    return a / b;
        }

    }

    由于程序代碼不會(huì)處理運(yùn)行時(shí)異常,因此當(dāng)程序在運(yùn)行時(shí)出現(xiàn)了這種異常時(shí),就會(huì)導(dǎo)致程序異常終止。以上程序的打印結(jié)果為:
    Exception in thread "main" java.lang.IllegalArgumentException: 除數(shù)不能為0
        at chapter09.d0903.WithRuntimeEx.divide(WithRuntimeEx.java:
    29)
        at chapter09.d0903.WithRuntimeEx.main(WithRuntimeEx.java:
    23)

    9.3.2 受檢查異常

    除了RuntimeException及其子類以外,其他的Exception類及其子類都屬于受檢查異常(Checked Exception)。這種異常要么catch語句捕獲,要么throws子句聲明拋出,否則編譯出錯(cuò)。

    9.3.3 區(qū)分運(yùn)行時(shí)異常和受檢查異常

    受檢查異常表示程序可以處理的異常。

    運(yùn)行時(shí)異常表示無法讓程序恢復(fù)運(yùn)行的異常,導(dǎo)致這種異常的原因通常是由于執(zhí)行了錯(cuò)誤操作。一旦出現(xiàn)了錯(cuò)誤操作,建議終止程序,因此Java編譯器不檢查這種異常。

    9.3.4 區(qū)分運(yùn)行時(shí)異常和錯(cuò)誤

    Error類及其子類表示程序本身無法修復(fù)的錯(cuò)誤,它和運(yùn)行時(shí)異常的相同之處是:Java編譯器都不會(huì)檢查它們,當(dāng)程序運(yùn)行時(shí)出現(xiàn)它們,都會(huì)終止程序。

    兩者的不同之處是:Error類及其子類表示的錯(cuò)誤通常是由Java虛擬機(jī)拋出。

    而RuntimeException類表示程序代碼中的錯(cuò)誤,它是可擴(kuò)展的,用戶可以根據(jù)特定的問題領(lǐng)域來創(chuàng)建相關(guān)的運(yùn)行時(shí)異常類。

    9.4 用戶定義異常

    9.4.1 異常轉(zhuǎn)譯和異常鏈

    public class BaseException extends Exception {

        
    protected Throwable cause = null;

        
    public BaseException() {

        }

        
    public BaseException(String msg) {
            
    super(msg);
        }

        
    public BaseException(Throwable cause) {
            
    this.cause = cause;
        }

        
    public BaseException(String msg, Throwable cause) {
            
    super(msg);
            
    this.cause = cause;
        }

        
    public Throwable initCause(Throwable cause) {
            
    this.cause = cause;
            
    return this;
        }

        
    public Throwable getCause() {
            
    return cause;
        }

        
    public void printStackTrace() {
            printStackTrace(System.err);
        }

        
    public void printStackTrace(PrintStream outStream) {
            printStackTrace(
    new PrintStream(outStream));
        }

        
    public void printStackTrace(PrintWriter writer) {
            
    super.printStackTrace(writer);

            
    if (getCause() != null) {
                getCause().printStackTrace(writer);
            }

            writer.flush();
        }
    }

    9.4.2 處理多樣化異常

    public class MultiBaseException extends Exception {

        
    protected Throwable cause = null;

        
    private List<Throwable> exceptions = new ArrayList<Throwable>();

        
    public MultiBaseException() {

        }

        
    public MultiBaseException(Throwable cause) {
            
    this.cause = cause;
        }

        
    public MultiBaseException(String msg, Throwable cause) {
            
    super(msg);
            
    this.cause = cause;
        }

        
    public List getException() {
            
    return exceptions;
        }

        
    public void addException(MultiBaseException ex) {
            exceptions.add(ex);
        }

        
    public Throwable initCause(Throwable cause) {
            
    this.cause = cause;
            
    return this;
        }

        
    public Throwable getCause() {
            
    return cause;
        }

        
    public void printStackTrace() {
            printStackTrace(System.err);
        }

        
    public void printStackTrace(PrintStream outStream) {
            printStackTrace(
    new PrintStream(outStream));
        }

        
    public void printStackTrace(PrintWriter writer) {
            
    super.printStackTrace(writer);

            
    if (getCause() != null) {
                getCause().printStackTrace(writer);
            }

            writer.flush();
        }
    }

    9.5 異常處理原則

    9.5.1 異常只能用于非正常情況

    9.5.2 為異常提供說明文檔

    9.5.3 盡可能地避免異常

    9.5.4 保持異常的原子性

    9.5.5 避免過于龐大的try代碼塊

    9.5.6 在catch子句中指定具體的異常類型

    9.5.7 不要在catch代碼塊中忽略被捕獲的異常,可以處理異常、重新拋出異常、進(jìn)行異常轉(zhuǎn)譯

    posted on 2008-02-22 17:50 CoderDream 閱讀(897) 評論(0)  編輯  收藏 所屬分類: Java-14.Exception

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    <2008年2月>
    272829303112
    3456789
    10111213141516
    17181920212223
    2425262728291
    2345678

    常用鏈接

    留言簿(9)

    我參與的團(tuán)隊(duì)

    隨筆分類(245)

    隨筆檔案(239)

    文章分類(3)

    文章檔案(3)

    收藏夾(576)

    友情鏈接

    搜索

    •  

    積分與排名

    • 積分 - 459735
    • 排名 - 114

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 最近免费中文字幕视频高清在线看| 免费av片在线观看网站| 污视频网站在线观看免费| h视频免费高清在线观看| 中国在线观看免费的www| 日本在线免费播放| 国产人成免费视频网站| 日韩免费观看的一级毛片| 亚洲乱码中文字幕综合234 | 88av免费观看| 最近2019中文字幕免费看最新 | 9久9久女女免费精品视频在线观看| 成人无遮挡裸免费视频在线观看 | 亚洲国产专区一区| 久久久久久亚洲精品| 亚洲色欲色欲www| fc2成年免费共享视频网站| 久久香蕉国产线看免费| 免费看香港一级毛片| 中文字幕精品亚洲无线码一区 | 亚洲依依成人亚洲社区| 国产精品美女久久久免费 | 在线永久看片免费的视频| 国产一级高清视频免费看| 国产aⅴ无码专区亚洲av| 亚洲日韩精品无码专区加勒比| 一区二区视频在线免费观看| 在线免费观看亚洲| 亚洲AV无码专区日韩| 久久综合亚洲色HEZYO社区| 精品一区二区三区免费毛片| 久久久久久国产精品免费免费男同| 女人被男人躁的女爽免费视频| 亚洲日韩中文无码久久| 亚洲午夜福利在线视频| 中文字幕在线免费看线人| 成人免费视频小说| 亚洲国产精品一区第二页| 亚洲av日韩av永久在线观看| 色欲色香天天天综合网站免费| 在线日韩av永久免费观看|