異常

模塊說明
先簡(jiǎn)介 從功能層面 為什么設(shè)計(jì)這個(gè) 為什么設(shè)計(jì)成這個(gè)樣子
然后可以跟一些重要的模塊 貼代碼過來
然后就是結(jié)合項(xiàng)目理解一哈 最好能對(duì)應(yīng)上之前梳理的設(shè)計(jì)理念

  • 異常處理的設(shè)計(jì)理念:把功能模塊代碼與系統(tǒng)中可能出現(xiàn)的錯(cuò)誤的處理代碼分離開來施籍,以此來達(dá)到使我們的代碼組織起來更美觀尸变、邏輯上更清晰痢畜,并且同時(shí)從根本上來提高我們軟件系統(tǒng)長時(shí)間穩(wěn)定運(yùn)行的可靠性
    Java中的異沉纺剑可以是函數(shù)中的語句執(zhí)行時(shí)引發(fā)的进副,也可以是程序員通過throw 語句手動(dòng)拋出的懊蒸,只要在Java程序中產(chǎn)生了異常瘩缆,就會(huì)用一個(gè)對(duì)應(yīng)類型的異常對(duì)象來封裝異常腿椎,JRE就會(huì)試圖尋找異常處理程序來處理異常米酬。
    http://www.importnew.com/26613.html這上面的圖

總體上我們根據(jù)Javac對(duì)異常的處理要求沛豌,將異常類分為2類。

非檢查異常(unckecked exception):Error 和 RuntimeException 以及他們的子類赃额。javac在編譯時(shí)加派,不會(huì)提示和發(fā)現(xiàn)這樣的異常,不要求在程序處理這些異常爬早。所以如果愿意哼丈,我們可以編寫代碼處理(使用try…catch…finally)這樣的異常,也可以不處理筛严。對(duì)于這些異常醉旦,我們應(yīng)該修正代碼,而不是去通過異常處理器處理 桨啃。這樣的異常發(fā)生的原因多半是代碼寫的有問題车胡。如除0錯(cuò)誤ArithmeticException,錯(cuò)誤的強(qiáng)制類型轉(zhuǎn)換錯(cuò)誤ClassCastException照瘾,數(shù)組索引越界ArrayIndexOutOfBoundsException匈棘,使用了空對(duì)象NullPointerException等等。

檢查異常(checked exception):除了Error 和 RuntimeException的其它異常析命。javac強(qiáng)制要求程序員為這樣的異常做預(yù)備處理工作(使用try…catch…finally或者throws)主卫。在方法中要么用try-catch語句捕獲它并處理,要么用throws子句聲明拋出它鹃愤,否則編譯不會(huì)通過簇搅。這樣的異常一般是由程序的運(yùn)行環(huán)境導(dǎo)致的。因?yàn)槌绦蚩赡鼙贿\(yùn)行在各種未知的環(huán)境下软吐,而程序員無法干預(yù)用戶如何使用他編寫的程序瘩将,于是程序員就應(yīng)該為這樣的異常時(shí)刻準(zhǔn)備著。如SQLException , IOException,ClassNotFoundException 等。

需要明確的是:檢查和非檢查是對(duì)于javac來說的姿现,這樣就很好理解和區(qū)分了(畢竟檢查異常孫哥下的是死命令)肠仪。(跑起來日志里看到exception都是unchecked exception,不然都不能編譯通過)

  • 看一哈異常
import java. util .Scanner ;
public class AllDemo
{
      public static void main (String [] args )
      {
            System . out. println( "----歡迎使用命令行除法計(jì)算器----" ) ;
            CMDCalculate ();
      }
      public static void CMDCalculate ()
      {
            Scanner scan = new Scanner ( System. in );
            int num1 = scan .nextInt () ;
            int num2 = scan .nextInt () ;
            int result = devide (num1 , num2 ) ;
            System . out. println( "result:" + result) ;
            scan .close () ;
      }
      public static int devide (int num1, int num2 ){
            return num1 / num2 ;
      }
}
/*****************************************
 
----歡迎使用命令行除法計(jì)算器----
0
Exception in thread "main" java.lang.ArithmeticException : / by zero
     at com.example.AllDemo.devide( AllDemo.java:30 )
     at com.example.AllDemo.CMDCalculate( AllDemo.java:22 )
     at com.example.AllDemo.main( AllDemo.java:12 )
 
----歡迎使用命令行除法計(jì)算器----
r
Exception in thread "main" java.util.InputMismatchException
     at java.util.Scanner.throwFor( Scanner.java:864 )
     at java.util.Scanner.next( Scanner.java:1485 )
     at java.util.Scanner.nextInt( Scanner.java:2117 )
     at java.util.Scanner.nextInt( Scanner.java:2076 )
     at com.example.AllDemo.CMDCalculate( AllDemo.java:20 )
     at com.example.AllDemo.main( AllDemo.java:12 )
*****************************************/

函數(shù)層級(jí)調(diào)用备典,有調(diào)用棧异旧,故有異常追蹤棧
---main(異常最先發(fā)生的地方,也稱異常拋出點(diǎn))
------CMDCalculate
---------devide
這個(gè)例子中沒有使用異常處理機(jī)制提佣,但是因?yàn)槭欠菣z查異常泽艘,所以可以順利編譯,但是這個(gè)異常會(huì)*冒泡到main镐依,main函數(shù)最終拋給JRE,導(dǎo)致程序終止

  • 異常處理機(jī)制
    多個(gè)catch塊順序執(zhí)行天试,如果異常有父子關(guān)系槐壳,應(yīng)該將子類異常放在前面,不然子類就沒有存在的意義了喜每。
    如果try中的異常沒有被捕獲务唐,就執(zhí)行finally,然后往上拋带兜。
    finally主要做一些清理工作枫笛,如流的關(guān)閉,數(shù)據(jù)庫連接的關(guān)閉等刚照。

有的編程語言當(dāng)異常被處理后刑巧,控制流會(huì)恢復(fù)到異常拋出點(diǎn)接著執(zhí)行,這種策略叫做:resumption model of exception handling(恢復(fù)式異常處理模式 )
而Java則是讓執(zhí)行流恢復(fù)到處理了異常的catch塊后接著執(zhí)行无畔,這種策略叫做:termination model of exception handling(終結(jié)式異常處理模式)

  • 異常的鏈化
    為了追蹤到異常的根源信息啊楚,我們用異常的鏈化
public class Throwable implements Serializable {
    private Throwable cause = this;
 
    public Throwable(String message, Throwable cause) {
        fillInStackTrace();
        detailMessage = message;
        this.cause = cause;
    }
     public Throwable(Throwable cause) {
        fillInStackTrace();
        detailMessage = (cause==null ? null : cause.toString());
        this.cause = cause;
    }
 
    //........
}

異常鏈化:以一個(gè)異常對(duì)象為參數(shù)構(gòu)造新的異常對(duì)象。新的異對(duì)象將包含先前異常的信息浑彰。這項(xiàng)技術(shù)主要是異常類的一個(gè)帶Throwable參數(shù)的函數(shù)來實(shí)現(xiàn)的恭理。這個(gè)當(dāng)做參數(shù)的異常,我們叫他根源異常(cause)郭变。
就是調(diào)試的時(shí)候看到的那個(gè)一層一層的cause.
注意到Throwable的數(shù)據(jù)結(jié)構(gòu)颜价,不就是個(gè)鏈表么。

  • 自定義異常
    參考IOException
package java.io;

/**
 * Signals that an I/O exception of some sort has occurred. This
 * class is the general class of exceptions produced by failed or
 * interrupted I/O operations.
 *
 * @author  unascribed
 * @see     java.io.InputStream
 * @see     java.io.OutputStream
 * @since   JDK1.0
 */
public
class IOException extends Exception {
    static final long serialVersionUID = 7818375828146090155L;

    /**
     * Constructs an {@code IOException} with {@code null}
     * as its error detail message.
     */
    public IOException() {
        super();
    }

    /**
     * Constructs an {@code IOException} with the specified detail message.
     *
     * @param message
     *        The detail message (which is saved for later retrieval
     *        by the {@link #getMessage()} method)
     */
    public IOException(String message) {
        super(message);
    }

    /**
     * Constructs an {@code IOException} with the specified detail message
     * and cause.
     *
     * <p> Note that the detail message associated with {@code cause} is
     * <i>not</i> automatically incorporated into this exception's detail
     * message.
     *
     * @param message
     *        The detail message (which is saved for later retrieval
     *        by the {@link #getMessage()} method)
     *
     * @param cause
     *        The cause (which is saved for later retrieval by the
     *        {@link #getCause()} method).  (A null value is permitted,
     *        and indicates that the cause is nonexistent or unknown.)
     *
     * @since 1.6
     */
    public IOException(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * Constructs an {@code IOException} with the specified cause and a
     * detail message of {@code (cause==null ? null : cause.toString())}
     * (which typically contains the class and detail message of {@code cause}).
     * This constructor is useful for IO exceptions that are little more
     * than wrappers for other throwables.
     *
     * @param cause
     *        The cause (which is saved for later retrieval by the
     *        {@link #getCause()} method).  (A null value is permitted,
     *        and indicates that the cause is nonexistent or unknown.)
     *
     * @since 1.6
     */
    public IOException(Throwable cause) {
        super(cause);
    }
}

一個(gè)無參構(gòu)造函數(shù)
一個(gè)帶有String參數(shù)的構(gòu)造函數(shù)诉濒,并傳遞給父類的構(gòu)造函數(shù)周伦。
一個(gè)帶有String參數(shù)和Throwable參數(shù),并都傳遞給父類構(gòu)造函數(shù)
一個(gè)帶有Throwable 參數(shù)的構(gòu)造函數(shù)循诉,并傳遞給父類的構(gòu)造函數(shù)横辆。
想要checked就擴(kuò)展Exception 想要unchecked就擴(kuò)展RuntimeException

  • 非人類的點(diǎn) finally塊和return
    在try塊中即便有return,break,continue等改變執(zhí)行流的語句狈蚤,fianlly也會(huì)執(zhí)行困肩,故finally中的return會(huì)抑制try catch中的異常,所以最好減輕finallyd的任務(wù)脆侮,盡量把return寫在函數(shù)的最后面锌畸,不要寫在異常處理過程中。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末靖避,一起剝皮案震驚了整個(gè)濱河市潭枣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌幻捏,老刑警劉巖盆犁,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異篡九,居然都是意外死亡谐岁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門榛臼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伊佃,“玉大人,你說我怎么就攤上這事沛善『饺啵” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵金刁,是天一觀的道長帅涂。 經(jīng)常有香客問我,道長胀葱,這世上最難降的妖魔是什么漠秋? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮抵屿,結(jié)果婚禮上庆锦,老公的妹妹穿的比我還像新娘。我一直安慰自己轧葛,他們只是感情好搂抒,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尿扯,像睡著了一般求晶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衷笋,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天芳杏,我揣著相機(jī)與錄音,去河邊找鬼。 笑死爵赵,一個(gè)胖子當(dāng)著我的面吹牛吝秕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播空幻,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼烁峭,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了秕铛?” 一聲冷哼從身側(cè)響起约郁,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎但两,沒想到半個(gè)月后鬓梅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谨湘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年己肮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悲关。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖娄柳,靈堂內(nèi)的尸體忽然破棺而出寓辱,到底是詐尸還是另有隱情,我是刑警寧澤赤拒,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布秫筏,位于F島的核電站,受9級(jí)特大地震影響挎挖,放射性物質(zhì)發(fā)生泄漏这敬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一蕉朵、第九天 我趴在偏房一處隱蔽的房頂上張望崔涂。 院中可真熱鬧,春花似錦始衅、人聲如沸冷蚂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蝙茶。三九已至,卻和暖如春诸老,著一層夾襖步出監(jiān)牢的瞬間隆夯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蹄衷,地道東北人忧额。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像宦芦,于是被迫代替她去往敵國和親宙址。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載:http://www.cnblogs.com/lulipro/p/7504267.html 一调卑、異常簡(jiǎn)介 程...
    SinX竟然被占用了閱讀 977評(píng)論 2 2
  • Java中的異常和處理詳解 簡(jiǎn)介 程序運(yùn)行時(shí)抡砂,發(fā)生的不被期望的事件,它阻止了程序按照程序員的預(yù)期正常執(zhí)行恬涧,這就是異...
    Richard2016閱讀 242評(píng)論 1 0
  • 引言 在程序運(yùn)行過程中(注意是運(yùn)行階段注益,程序可以通過編譯),如果JVM檢測(cè)出一個(gè)不可能執(zhí)行的操作溯捆,就會(huì)出現(xiàn)運(yùn)行時(shí)錯(cuò)...
    Steven1997閱讀 2,435評(píng)論 1 6
  • 就像宮崎駿《哈爾的移動(dòng)城堡》里說的那樣:愛谎仲,不是尋找一個(gè)完美的人,而是學(xué)會(huì)用完美的眼光刨仑,欣賞那個(gè)并不完美的人郑诺。 也...
    秋水盈盈999閱讀 148評(píng)論 0 1
  • 因?yàn)榭戳死钤铝恋囊黄恼率玻韵矚g上了她曾沈。滿世界找她的作品,一眼看到書名《愛比現(xiàn)實(shí)高半米》量淌,就心心念念轻抱,熬夜看完過...
    盈盈她說閱讀 976評(píng)論 0 1