成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

java:異常處理

LuDongWei / 2883人閱讀

摘要:異常處理機制異常與異常類的繼承體系在程序中,當(dāng)程序出現(xiàn)意外情況時,系統(tǒng)會自動生成一個來通知程序,從異常發(fā)生出逐漸向外傳播,如果沒有人來處理該異常,就會交給來處理,對異常的處理方法是,打印異常跟蹤棧信息,并中止程序的執(zhí)行。

1 為什么要處理異常?

異常機制可以使程序的異常處理代碼與正常業(yè)務(wù)代碼分離,保證程序代碼的健壯性。
在設(shè)計程序的時候,好的程序需要盡可能處理已知的可能產(chǎn)生的錯誤,但是事實上并不可能考慮到所有可能產(chǎn)生異常的情況,同時,眾多的類似if-else的錯誤處理代碼可能會帶來很多的代碼冗雜,錯誤處理與業(yè)務(wù)代碼混雜的情況,帶來閱讀和維護的難度。因此我們需要合適的異常處理機制。
java的異常機制依靠于try,catch,finally,throw,throws關(guān)鍵字,其中try塊中通常放置可能引發(fā)異常的代碼,catch后對應(yīng)異常類型和響應(yīng)的異常處理代碼塊,finally塊在java異常機制中總是會被執(zhí)行,通常用于回收try塊中打開的物理資源,throw用于拋出一個實際的異常(異常的實例),throws主要在方法簽名中使用,用于聲明該方法可能會拋出的異常,方便或者提醒方法的使用者來捕獲并處理異常。
2 異常處理機制

2.1 異常與異常類的繼承體系

在java程序中,當(dāng)程序出現(xiàn)意外情況時,系統(tǒng)會自動生成一個Exception來通知程序,從異常發(fā)生出逐漸向外傳播,如果沒有人來處理該異常,就會交給jvm來處理,jvm對異常的處理方法是,打印異常跟蹤棧信息,并中止程序的執(zhí)行。
java提供了豐富的異常類體系,所有的異常類都繼承自Throwable父類

java異常處理體系.jpg
注意:
Error錯誤:一般與虛擬機相關(guān),如系統(tǒng)崩潰,動態(tài)鏈接錯誤等,這種錯誤無法恢復(fù)也無法捕獲,所以應(yīng)用程序一般不能處理這些錯誤,也不應(yīng)該試圖去捕獲這類對象
我們主要處理的Exception類,該類在java中分為兩類,一種是Checked異常,一種是Runtime異常。Checked異常是java特有的,在java設(shè)計哲學(xué)中,Checked異常被認(rèn)為是可以被處理或者修復(fù)的異常,所以java程序必須顯式處理Checked異常,當(dāng)我們使用或者出現(xiàn)Checked異常類的時候,程序中要么顯式try- catch捕獲該異常并修復(fù),要么顯式聲明拋出該異常,否則程序無法通過編譯。(Checked異常某種程度上降低了開發(fā)生產(chǎn)率和代碼執(zhí)行率,在java領(lǐng)域是一個備受爭論的問題)
常見的運行時異常:如上圖所示,這里列舉幾個比較常見的。

public class test{
    public static void main(String[] args){
        try{
            int a = Integer.parseInt(args[0]);
            int b = Integer.parseInt(args[1));
            int c = a/b;
            System.out.println("您輸出的結(jié)果是"+c);
        }
        catch(IndexOutOfBoundsException ie){
            System.out.println("數(shù)組越界,輸入的參數(shù)不夠");
        }
        catch(NumberFormatException ne){
            System.out.println("數(shù)字格式異常:程序只能接收整數(shù)參數(shù)");
        }
        catch(ArithmeticException ae){
            System.out.println("算術(shù)法異常");
        }
        catch(Exception e){
            System.out.println("出現(xiàn)異常");
        }
        
        Date d = null;
        try{
            System.out.println(d.after(new Date()));
        }
        // 試圖調(diào)用一個null對象的方法或者實例變量時 出現(xiàn)的異常
        catch(NullPointerException ne){
            System.out.println("指向異常");
        }
    }
}

程序中一般將Exception放在最后,先捕獲小異常(子類異常),再捕獲大異常。如果順序顛倒,還會出現(xiàn)編譯錯誤。
2.2 try ... catch異常捕獲

try ... catch 是最常見的異常捕獲語句,try后與{ }配對使用,其中是業(yè)務(wù)實現(xiàn)代碼,如果try塊中出現(xiàn)問題或者異常,系統(tǒng)自動生成一個異常對象,該異常對象提交到Java運行環(huán)境,java運行環(huán)境收到異常對象后,會尋找能夠處理該異常的catch塊,如果找到,就將異常對象交給該catch塊處理,如果沒有找到,就終止程序運行。

從異常捕獲過程中,我們可以看到程序要慎重考慮可能出現(xiàn)異常的代碼塊,否則這段程序是不夠健壯的,一個經(jīng)常出現(xiàn)崩潰或被終止的程序,是災(zāi)難性的。

catch塊中如何處理異常:

一個try塊之后可能存在多個catch塊,java運行時與catch塊()內(nèi)的異常類進行比較,判斷該異常是否 instanceof 該類,如果屬于該類,就將該異常對象傳給catch塊內(nèi)的異常形參,catch塊后可以對該異常進行處理,獲取相關(guān)異常的詳細信息等。注意系統(tǒng)生成的異常實例對象是相對具體的子類異常對象,而進入一個catch塊后就不會再進入下一個catch塊,所以這也是我們盡量將小異常放在大異常前面的原因。
常見操作:輸出出現(xiàn)異常提示信息
訪問異常信息,打印異常信息

getMessage();// 返回詳細描述字符串 
printStackTrace();// 打印異常跟蹤棧信息到標(biāo)準(zhǔn)錯誤窗口
printStackTrace(PrintStream s);// 跟蹤棧信息輸出到指定輸出流
getStackTrace();// 返回跟蹤棧信息

采用別的替選數(shù)據(jù)或方案,或者提示用戶重新操作,或者重新拋出異常,進行異常轉(zhuǎn)譯,重新包裝,交給上層調(diào)用者來對該異常進行處理。
多異常捕獲:(java 7 提供的新特性)

public class test{
    public static void main(String[] args){
        try{
            int a = Integer.parseInt(args[0]);
            int b = Integer.parseInt(args[1));
            int c = a/b;
            System.out.println("您輸出的結(jié)果是"+c);
        }
        catch(IndexOutOfBoundsException ie | NumberFormatException ne
             |ArithmeticException ae){
            System.out.println("程序發(fā)生上述異常的某一種");
            // 此時ie ,ne, ae都是默認(rèn) final修飾的變量 不能再重新賦值
        }
        catch(Exception e){
            System.out.println("出現(xiàn)異常");
            // 此時可以賦值
            e = new RuntimeException("new error");
        }
        
    }
}

2.3 finally 一定會執(zhí)行的finally模塊

通常try塊里打開了一些物理資源,(比如磁盤文件,數(shù)據(jù)庫連接等),這些需要保證回收,所以我們通常在finally塊中進行回收。
舉個例子

public class test{
    public static void main(String[] args){
        FileInputStream fis = null;
        try{
            fis = new FileInputStream("a.txt");
        }
        catch(IOException e){
            System.out.println(e.getMessage);
            
            //如果執(zhí)行return,程序會先跳到finally塊執(zhí)行,執(zhí)行完之后再回來執(zhí)行return語句
            return;
            // 如果這里是System.exit(0),因為是退出虛擬機
            // 所以finally塊沒辦法執(zhí)行
        }
        finally{
            if(fis!= null){
                try{
                    fis.close();
                }
                catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

注意:盡量不要在finally塊中使用return或者throw語句,因為一旦在finally中執(zhí)行,程序就不會再跳回原來try或者catch塊中執(zhí)行原本應(yīng)該執(zhí)行的return和throw語句了,程序自己就結(jié)束了,這可能會帶來一些麻煩的錯誤。
為了方便物理資源的關(guān)閉,java7 提供了一種新的語法,增強了try的功能,可以在try后面跟一對圓括號,來聲明初始化物理資源,try執(zhí)行完畢后會自動關(guān)閉資源。

public class AutoClose{
    public static void main(String[] args)
    throws IOException
    {
        // ()內(nèi)的資源類必須實現(xiàn)AutoCloseable 或者Closeable接口中的close()方法
        try(BufferedReader br  = new BufferedReader(
        new FileReader("auto.java")))
        {
            System.out.println(br.readLine());
        }
        
    }
}

2.4 throws 關(guān)鍵字:聲明拋出異常

throws聲明拋出異常,在方法簽名中使用,上面的AtuoClose就是其使用的例子。它可以聲明拋出多個類,多個類之間用“,”隔開。

首先要理解我們?yōu)槭裁匆暶鲯伋霎惓#寒?dāng)某個方法中程序的執(zhí)行可能會出現(xiàn)異常,但是該方法并不知道如何處理異常,或者我們想把這個異常交給上層方法調(diào)用者來處理或者修復(fù),那我們給該方法加上關(guān)鍵字throws 異常,以聲明該方法可能會出現(xiàn)的異常。自然,加了throws關(guān)鍵字之后,該方法我們就無需再用try—catch來捕獲異常了,因為這已經(jīng)不是我們這個方法需要操心的事情了。

注意使用throws聲明異常的時候,涉及到子類對父類的方法重寫時,子類聲明的異常類型應(yīng)該是父類方法聲明的異常類型的子類或者相同類。

如果throws 聲明的是checked異常,根據(jù)checked異常的規(guī)定,我們不能對該異常視而不見,因為我們必須處理該異常,所以當(dāng)拿到一個聲明了可能會發(fā)生checked異常的方法時,在調(diào)用該方法時,要么放在try塊中來顯式捕捉該異常,要么放在另外一個帶throws聲明異常的方法中。
所以使用checked異常時,要特別注意處理它的問題,還會帶來方法重寫的限制性,因此大部分時候推薦使用Runtime異常。

public class ThrowTest{
    public static void main(String[] args)
    throws Exception
    {
        test();//test 聲明會產(chǎn)生checked 異常 因此main函數(shù)也需要聲明異常
        // 或者在try - catch 中捕獲該異常
    }
    
    public void test() throws IOException{
        FileInputStream fis = new FileInputStream("a.text");
    }

}

2.5 throw關(guān)鍵字 :拋出異常

java允許程序自行拋出異常,通常系統(tǒng)幫助我們檢查是否發(fā)生一些普遍定義的異常,但是有些異??赡懿皇瞧毡槎x的,只是與我們業(yè)務(wù)不符,所以我們可以自行拋出異常,也可以自行拋出一些我們自定義的異常,而拋出異常的行為與系統(tǒng)拋出異常的行為一定程度上是等價的,后續(xù)處理方式也是一樣的,在這里我們使用throw關(guān)鍵字。

throw語句可以多帶帶使用,注意它拋出的是一個異常實例。

try{
    // do something...
    throw new Exception("hhh 我是新異常");  // 異常實例
}
catch{
    System.out.println("出現(xiàn)異常");
    continue;
}

當(dāng)我們自行拋出的異常是checked異常的時候,該throw語句要么是在如上面例子中的try塊中,顯示捕獲,要么是在一個已經(jīng)用throws聲明會出現(xiàn)異常的方法中,而如果我們拋出的是runtime異常,那么情況就很簡單了,它無需在try塊中,也不需要將對應(yīng)的方法用throws聲明,如果我們想要處理,就捕獲處理它,不管是在它自身方法體內(nèi),或者是對應(yīng)方法者,也可以不去理會,當(dāng)然我們自己拋出的異常,通常情況下是要處理的,不然拋出去之后不管最后只能中斷程序運行了,只不過拋出是runtime異常時,在編譯時沒有那么嚴(yán)格。

自定義異常類:前面說了,系統(tǒng)會拋出一些普遍意義的異常,那么我們也就沒必要再自己操心throw了,通常throw的是自定義的異常類。

自定義異常類都應(yīng)該繼承Exception類,或者Exception下的子類如runtime異常
定義異常類的時候需要提供兩個構(gòu)造器,一個無參構(gòu)造器,一個帶一個字符串參數(shù)的構(gòu)造器,這串字符串實際上是getMessage() 時返回的異常對象的詳細描述信息。

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

catch中throw(拋出)異常:有時候我們在本方法中捕捉了異常,我們只能處理異常的一部分,我們還需要別的方法來處理或者我們想把產(chǎn)生了異常的這個信息告訴調(diào)用者,這個時候我們通常捕捉了異常后會在catch塊中拋出我們想拋出的異常
在企業(yè)級應(yīng)用中,通常對異常處理分為兩部分:應(yīng)用后臺打印或者通過日志記錄異常發(fā)生時詳細情況(異常跟蹤棧)和向使用者傳達某種提示。
java 7 中增強了throw語句:java 7 編譯器執(zhí)行更細致檢查,檢查拋出的異常的具體類型。

public class Test{
    private double initprice = 30.0;
    // 自定義的異常 
    // 方法中拋出了異常 所以此處要聲明異常
    public void bid(String bidprice) throws AuctionException{
        double d =0.0;
        try{
            d = Double.parseDouble(bidprice);
        }
        catch(Exception e){
            e.printStackTrace();
            throw new AuctionException("新異常");
            
            //這里也可以拋出e 但是我們通常會拋出我們包裝過后的異常
            // 用來向方法調(diào)用者或者上層提示某種信息 而不會直接暴露異常的原因
            // throw e; 
            // 如果這里throw e 在java7 以前不會做細致檢查,throws聲明那里必須聲明為Exception
            // 但是java7 之后可以聲明為更細致的異常子類型
            
        }
    }
    public static void main(String[] args){
        Test test = new Test();
        try{
            test.bid("df");
        }
        catch(AuctionException ae){
            System.err.println(ae.getMessage);
        }
    }
}

異常鏈:異常轉(zhuǎn)譯與異常鏈
3. 異常處理的一些基本規(guī)則

3.1 異常跟蹤棧

異常是從里向外傳播,可以很方便跟蹤異常的發(fā)生情況,可以用來調(diào)試程序,但在發(fā)布的程序中,應(yīng)該避免使用,而是將異常進行適當(dāng)?shù)奶幚怼?br>3.2 不要過度使用

異常的運行效率會差一些,因此如果不是那種不可預(yù)期的錯誤,應(yīng)該避免使用異常,而是放在正常的業(yè)務(wù)判斷或者處理邏輯中。
3.3 不要使用過于龐大的try塊

為了更好的判斷發(fā)生的異常的類型,應(yīng)該將大塊try塊分割為多個可能出現(xiàn)異常的try段落。
3.4 避免catch-all

類似上面的理由,更好的區(qū)分度,更好的異常判斷
3.5 不要忽略異常

避免catch塊為空,或者僅僅打印出異常情況,我們還是要處理異常,比如繞過異常發(fā)生的地方,或者采用別的替選數(shù)據(jù)或方案,或者提示用戶重新操作,或者重新拋出異常,進行異常轉(zhuǎn)譯,重新包裝,交給上層調(diào)用者來對該異常進行處理。

歡迎加入學(xué)習(xí)交流群569772982,大家一起學(xué)習(xí)交流。

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

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

相關(guān)文章

  • 16.java異常處理

    摘要:不受檢查異常為編譯器不要求強制處理的異常,檢查異常則是編譯器要求必須處置的異常。潛在的異常處理器是異常發(fā)生時依次存留在調(diào)用棧中的方法的集合。當(dāng)運行時系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器,則運行時系統(tǒng)終止。異常處理涉及到五個關(guān)鍵字,分別是。 概念 程序運行時,發(fā)生的不被期望的事件,它阻止了程序按照程序員的預(yù)期正常執(zhí)行,這就是異常。 異常是程序中的一些錯誤,但并不是所有的錯誤都是異常,并...

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

    摘要:異常也就是指程序運行時發(fā)生錯誤,而異常處理就是對這些錯誤進行處理和控制。有兩個重要的子類異常和錯誤,二者都是異常處理的重要子類,各自都包含大量子類。需要注意的是,一旦某個捕獲到匹配的異常類型,將進入異常處理代碼。 1,異?,F(xiàn)象 程序錯誤分為三種:1,編譯錯誤;2,運行時錯誤;3,邏輯錯誤。 編譯錯誤是因為程序沒有遵循語法規(guī)則,編譯程序能夠自己發(fā)現(xiàn)并且提示我們錯誤的原因和位置,這...

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

    摘要:可以被異常處理機制使用,是異常處理的核心。非檢測異常,在編譯時,不會提示和發(fā)現(xiàn)異常的存在,不強制要求程序員處理這樣的異常??傮w來說,語言的異常處理流程,從程序中獲取異常信息。處理運行時異常,采用邏輯合理規(guī)避同時輔助處理。 目錄 什么是Java異常? 當(dāng)一個Exception在程序中發(fā)生的時候,JVM是怎么做的呢? 當(dāng)我們編寫程序的時候如何對待可能出現(xiàn)的異常呢? 正文 1. 什么是J...

    Fourierr 評論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異常處理機制的理解

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

    khs1994 評論0 收藏0
  • Java異常處理 10 個最佳實踐

    摘要:為可恢復(fù)的錯誤使用檢查型異常,為編程錯誤使用非檢查型錯誤。檢查型異常保證你對錯誤條件提供異常處理代碼,這是一種從語言到強制你編寫健壯的代碼的一種方式,但同時會引入大量雜亂的代碼并導(dǎo)致其不可讀。在編程中選擇檢查型異常還是運行時異常。 異常處理是Java 開發(fā)中的一個重要部分。它是關(guān)乎每個應(yīng)用的一個非功能性需求,是為了處理任何錯誤狀況,比如資源不可訪問,非法輸入,空輸入等等。Java提供了...

    Forelax 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<