天天看點

java SE day16 火推異常處理

異常處理

異常結構中 表示範圍最大的是  Throwable類 , 他有兩個子類: 
Error 和 Exception

我們要處理的是 Exception(異常) . 

Error(錯誤) 無法處理, 隻能盡量避免 !
           

Exception ***

運作時異常 (非受檢異常)(RuntimeException):  程式在執行過程中, 因為邏輯問題, 産生了異常 !

非運作時異常(受檢異常) :  編譯器可檢測異常 , 在編寫代碼進行javac操作時,  提示的異常 !
           

RuntimeException *****

當程式遇到異常時, 如果不對其進行異常處理, 程式會異常終止 !
           
try catch語句塊 *****
我們可以在異常産生時, 通過try塊捕獲異常 , 通過catch塊處理異常 

如果try塊捕獲的異常, 與catch塊聲明的接收異常類型都不同, 則與沒有異常處理一緻!


格式:  

try{
    //異常捕獲代碼塊, 
    //在這裡的代碼 出現異常後, 會自動捕獲異常
    //忽略try塊後續代碼, 立即,将異常傳遞到catch塊中進行處理
    //如果未産生異常, 則忽略catch塊
}catch(異常類型1 異常名1){

}catch(異常類型2 異常名2){
    ...
}catch(異常類型n 異常名n){

}

關于多個catch塊中異常聲明的規則: 

    類型越大的(父類異常) , 越靠後 !

    例如:

    try{
        ....
    }catch(NumberFormatException e){

    }catch(Exception e){

    }
           

特殊的判斷結構

如果try塊的最後一句代碼能正确執行 , 則表示try塊未産生異常 !

    try {
        int i = Integer.parseInt("0");

        System.out.println("如果這裡執行了, 表示沒有産生異常!");
    }catch(Exception e) {
        System.out.println("如果這裡執行了, 表示産生異常!");
    }
           

為什麼出現了異常以後, 會在控制台列印異常的堆棧資訊

原因在于, 出現了異常後,  我們并未自行進行處理, jvm幫我們執行了輸出到控制台的處理方式 !
           

finally ***

是異常的統一出口 ! 無論在任何的情況下, 隻要代碼進入了try塊中, finally塊必然會執行!

需要注意: 

    哪怕在try 或 catch塊中執行了return , 也阻擋不了finally的執行


----------------------------------------------

我們一般在這裡執行什麼樣的操作: 

    一般用來執行資源釋放的操作(硬體軟體資源) !

格式:  

try{

}catch(){

}finally{
    // 無論上述的代碼塊 是否産生了異常,  最後finally都會執行 !
}
           

面試題:*****

觀察如下代碼,finally中的列印語句 會執行嗎 ? 

public static int numberFormat(String text) {
    try {
        int i = Integer.parseInt(text);
        return i;
    }catch(NumberFormatException e) {
        e.printStackTrace();
        return 0;
    }finally {
        System.out.println("程式執行完畢, 已經轉換了一個數字");
    }
}


答: 

    隻要代碼執行了try塊, 那麼finally必然會執行, 無論是否有return操作!
           

throws **

在程式中, 我們對于異常 并非隻能捕獲, 還可以将其進行抛出操作 , 留待後續調用時再處理 !

異常的抛出, 必須在方法上聲明

格式:  

    方法名()throws 抛出的異常類型{

    }

例如: 

    public static int numberFormat(String text)throws NumberFormatException{
        int i = Integer.parseInt(text);
        return i;
    }


當調用一個抛出了異常的方法時, 如果抛出的類型屬于RuntimeException或它的子類, 則不會在調用處提示;

如果調用的方法 抛出了一個 受檢異常 , 則編譯器 會強制我們進行處理 !


如果将異常抛出到main方法上, 則表示将異常交給jvm去處理 !  會造成程式的異常終止 !
           

主動建立一個異常, 并扔出去**

異常類型 對象名 = new 異常類型();

throw 異常對象名;


異常的構造方法:  

    無參構造: 建立一個異常對象,  不包含異常的消息内容


一參構造器 ,

    參數1. 傳入的是字元串類型的值, 表示異常的消息 !


案例:

    public void setAge(int age)throws RuntimeException {
        /**
         * 如果傳入 的年齡範圍不在0-150之間, 則抛出異常
         */
        if(age<0||age>150) {
            // 建立一個異常對象, 将其扔出去
            AgeExceptionNiFengLe e = new AgeExceptionNiFengLe("你是不是薩 , 年齡傳入的有問題, 請檢查");
            throw e;
        }
        this.age = age;
    }
           

繼承一個異常類, 實作自定義異常*

繼承異常類後, 不建議重寫任何方法!   

僅編寫兩個構造方法即可, 一個是無參構造器, 一個是一參字元串的構造器 !

案例: 

    public class AgeExceptionNiFengLe extends RuntimeException {
        public AgeExceptionNiFengLe() {
            super();
        }
        public AgeExceptionNiFengLe(String message) {
            super(message);
        }
    }
           

關于方法的重寫 與異常的問題

父接接口中的方法, 或 父類中的方法聲明的抛出異常, 

子類在進行重寫時, 子類扔出的異常 不能大于 父類扔出的異常 !

并且 子類扔出的異常 ,不能是額外的異常 (不屬于父類聲明範圍内的)

總結:  隻能扔出 父類聲明異常的類型, 或父類聲明異常類型的子類 !
           

IO

File類

檔案或檔案夾 在JAVA 中的抽象表示形式

在建立對象時, 檔案可以是不存在的 !
           

常用構造方法

1.  File(File parent,String child); ***
    參數1. 表示父檔案夾File對象
    參數2. 表示子檔案的檔案名稱(包含字尾名)


2.  File(String parent,String child);   *
    參數1. 表示父檔案夾的路徑
    參數2. 表示子檔案的檔案名稱(包含字尾名)


3.  File(String pathName);  *****
    參數1. 表示檔案的路徑
           

常用方法

booolean createNewFile()
    當對象表示的檔案不存在時, 建立檔案且傳回true , 如果檔案已存在, 不會執行操作 ,直接傳回false
boolean mkdir()
    建立一層目錄 

boolean mkdirs() *** 
    建立此對象表示的目錄 , 包括所有目錄中必須有,但不存在的父路徑 !

boolean delete();
    删除此對象表示的檔案或檔案夾  
boolean exists()*
    測試此檔案或者檔案夾是否存在  , 存在則傳回true, 不存在則傳回false

String getAbsolutePath(); **
    擷取檔案或目錄的絕對路徑

long length():*
    擷取檔案的大小長度 (byte為機關)

long lastModified():
    檔案最後一次被修改的時間

String getName()***
    傳回檔案或檔案夾的名稱(如果是檔案,包含字尾名)

String getPath()
    傳回檔案的路徑

boolean isFile()*
    判斷目前對象表示的是否是檔案, 是檔案則傳回true, 檔案夾則傳回false

String[] list()
    傳回目前檔案夾中所有的直接子檔案與直接子檔案夾的檔案名!
File[] listFiles() ***
    傳回目前檔案夾中, 所有的直接子檔案/直接子檔案夾的  File對象
File getParentFile()
    擷取直接父檔案夾的file對象

renameTo(File newFile)

給一個檔案重新命名, 可以通過這個方式, 對其實作剪切的操作
           

練習:

掃描電腦的D盤 , 輸出盤下的所有的檔案與檔案夾!  

使用遞歸來完成


設計一個方法 , 這個方法 具備如下功能:  

形式參數, 要求傳入一個File數組, 

我們對這個File數組進行周遊 , 

判斷每一個File對象是否是檔案, 如果是檔案, 則輸出其檔案名稱 , 檔案最後修改時間, 檔案的大小

如果是檔案夾, 則輸出檔案夾名稱, 并通過檔案夾的listFiles方法 擷取所有子檔案與子檔案夾



public static void printFiles(File[] files){
    for(File file:files){
        if(file.isFile()){
            //這是一個檔案
            System.out.println("發現一個檔案:檔案名稱:"+file.getName()+",最後一次修改:"+file.lastModified()+",檔案的大小:"+file.length());
        }else{
            //這是一個檔案夾
            System.out.println("發現了一個檔案夾, 檔案夾的名稱:"+file.getName()+",正在準備周遊内部檔案");
            File[] files2 = file.listFiles();
            printFiles(files2);
        }
    }
}