模塊說明
先簡(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ù)的最后面锌畸,不要寫在異常處理過程中。