JavaSEday05異常和線程

day05_面向對象(異常、線程)
    一.異常
        1.什麼是異常
            代碼執行過程中的出現的問題
            ArrayIndexOutOfBoundsException
            NullPointerExceptioin
        2.異常的繼承體系*************
            Throwable 異常的根類
                - Error 錯誤類
                - Exception    異常類
                    -編譯時異常 Exception類以及其子類(RuntimeException除外)
                    -運行時異常 RuntimeException以及其子類
        3.異常類中常用的三個方法
            public void printStackTrace():打印異常的詳細信息(包括異常信息、異常原因以及異常位置)*****************
            public String getMessage():獲取異常的原因
            public String toString():返回異常的類型和異常的信息 
        4.異常的分類
            i.編譯時異常
                Exception類以及其子類(RuntimeException除外)
                編譯時異常,會在編譯時報錯!!!
            ii.運行時異常
                RuntimeException以及其子類
                運行時異常,編譯器不報錯,直到運行時才報錯!!!
        5.JVM異常產生過程(畫圖演示)
 
    二.異常的處理
        1.模擬JVM拋出異常(關鍵字throw)
            throw:表示拋出一個異常對象會中斷處理(結束程序運行)
            格式:
                throw 異常對象;
public class ExceptionDemo02 {
    public static void main(String[] args) {
        //調用方法
        int[] arr = null;
        method(arr);
    }

    //模擬JVM拋出異常
    public static void method(int[] arr) {
        //判斷 arr 是不是 null
        if (arr == null) {
            throw new NullPointerException("哥們您的數組是null啊~~~~");
        }

        //判斷 arr 有沒有第二個元素
        if (arr.length <= 1) {
            throw new ArrayIndexOutOfBoundsException("哥們您的數組要越界了~~~~");
        }

        //取出第二個元素
        int num = arr[1];
        System.out.println(num);
    }
}

        2.Objects類中提供的非空判斷方法
            Objects類是一個工具類,所有的方法都是靜態的
            public static<T> T requireNonNull(T obj){
                if (obj == null){
                    throw new NullPointerException();
                }
                return obj;
            }
        3.遇到異常的的兩種處理方式******************
        ①throws聲明拋出異常
            throws這個關鍵字使用修飾修飾方法的,聲明該方法的調用者必須處理異常
            格式:
                public static void 方法名(參數列表)throws 異常類名1,異常類名2,...{
                } 
            第一種處理方式:不處理,再次聲明拋出
        ②try...catch捕獲異常   (允許程序局部異常,代碼正常運行)
            第二種處理方式:捕獲處理,把異常對象抓住
            格式:
                try{
                    可能出現異常的代碼
                }catch (XxxException e){
                    自己處理異常對象e
                }
                之後能正常運行代碼    
        4.[擴展1]catch代碼塊中三種常見的處理方法
            a.在開發階段:直接打印到控制檯
            b.在測試階段:寫到日誌文件中或數據庫中
            c.在上線階段:先把錯誤日誌保存到本地,在適當的時機上傳到服務器(連接wifi的時候)
        5.[擴展2]多個異常如何獲取處理
            method01():可能拋出OneException
            method02():可能拋出TwoException
            method03():可能拋出ThreeException
            
            a.第一種方式:每個異常單獨處理
                try{
                    method01(); // 可能拋出OneException
                }catch(OneException e){
                    e.printStackTrace();
                }
                try{
                    method02(); // 可能拋出TwoException
                }catch(TwoException e){
                    e.printStackTrace();
                }
                try{
                    method03(); // 可能拋出ThreeException
                }catch(ThreeException e){
                    e.printStackTrace();
                }
            b.第二種方式:多個異常統一處理*******(用的最多)
                try{
                    method01(); //可能拋出OneException
                    method02(); //可能拋出TwoException
                    method03(); //可能拋出ThreeException
                }catch(Exception e){  //異常類型應該是以上可能異常的父類
                    e.printStackTrace();
                }
            c.第三種方式:多個異常分別處理
                try{
                    method01(); //可能拋出OneException
                    method02(); //可能拋出TwoException
                    method03(); //可能拋出ThreeException
                }catch(OneException e1){
                    直接打印
                }catch(TwoException e2){
                    寫到異常日誌
                }catch(ThreeException e3){
                    不管他
                }
                注意:
                    假設OneException是TwoException的子類,那麼在catch必須先catch子類異常對象,再catch父類異                        常對象,因爲多態,如果TwoException放在OneException前面,OneException和TwoException均會被TwoException處理方法catch,OneException的處理方法catch不到異常

        6.finally代碼塊
            finally被稱爲必須要執行的代碼塊
            格式:
                try{
                    可能出現異常的代碼
                }catch(XxxException e){
                    處理異常
                }finally{
                    必須要執行的代碼
                }
        必須要執行的代碼是指釋放資源的代碼
            比如:關閉文件的IO流(不關閉下次文件無法打開),關閉數據庫連接,關閉網絡連接(網絡服務器的連接個數有限)。
流氓軟件原理:後臺總會開啓一個程序或線程,所以你無法卸載。            
三線程守護:有三個線程同時在後臺運行,一旦一個線程被關閉,其他兩個線程又會把他打開。
文件粉碎:不管程序有沒有運行,強制在操作系統的層面上進行文件刪除操作。
        7.異常的注意事項
            a.運行時異常,在編譯階段不需要聲明也不需要捕獲
            b.父類的方法拋出多個異常,子類在重寫該方法只能拋出這些異常的子集
            c.如果父類的方法沒有拋出異常,子類重寫該方法時必須也不能拋出異常
            d.如果有多個catch,那麼必須先catch子類異常,再catch父類異常
            e.trycatch後面可以finally,一般用於資源回收
            f.多個異常如何捕獲處理
                i.每個異常單獨catch
                ii.多個異常一個try一個catch
                iii.多個異常一個try多個catch
        總結:
            a.如果寫代碼過程中,沒有異常,就當作沒學一樣
            b.如果遇到編譯時異常,要麼throw要麼try
            c.如果遇到運行時異常,運行時程序程序崩潰了根據異常信息修改代碼
    三.自定義異常
        1.爲什麼要定義異常
            因爲JDK所定義的異常類不可能描述所有問題,所以需要自定義異常
        2.自定義異常的步驟
            a.創建一個異常類,該類必須叫做XxxException
            b.該類必須繼承Exception或者RuntimeException
            c.自定義異常類至少提供兩個構造
                i.空參構造
                ii.帶有異常信息的String參數構造
//1.異常類以Exception結尾
public class MyException extends /*Exception*/ RuntimeException { //2.繼承Exceptoin 或者 RuntimeException

    //2.提供兩個構造
    public MyException(){}

    public MyException(String message){
        super(message);
    }
}

        3.自定義異常的練習(代碼演示)
/**
 * 用戶名已經存在異常:
 *      描述註冊時用戶名存在這種情況
 */
public class UserNameExistsException extends Exception{
    public UserNameExistsException() {
    }

    public UserNameExistsException(String message) {
        super(message);
    }
}

public class TestDemo {
    public static void main(String[] args) {
        //模擬註冊
        System.out.println("請輸入一個用戶名:");
        String username = new Scanner(System.in).nextLine();
//        調用方法
        try {
            register(username);
        } catch (UserNameExistsException e) {
            e.printStackTrace();
        }
    }

    //定義方法:註冊用戶
    public static void register(String username) throws UserNameExistsException {
        //查詢數據庫,該用戶名是否被註冊過
        //假設 jack 這個用戶已經被註冊了
        if (username.equals("jack")) {
            //不能註冊
            throw new UserNameExistsException("親,該用戶名已經被註冊~~~");
        } else{
            System.out.println("恭喜您"+username+"註冊成功~~~");
        }
    }
}


    四.多線程************************
        1.並行和併發
            並行:兩個事件同一時刻都在進行
            併發:兩個事件同一時間段內存都在進行,精確到時刻是交替運行
        2.進程和線程:
            進程:在內存中正在運行的程序
            線程:進程中完成特定功能的執行單元
            進程和線程的一些區別(瞭解)
                a.一個進程中可能包含多個線程,這種有多個線程的進程,我們稱爲多線程進程,對應的有單線程進程
                b.進程用戶獨立的堆和獨立的棧(進程間可以通過操作系統進行通信,JDNI)
                c.線程也擁有獨立的棧,但是線程共享進程的堆(線程之間可以互相通信) 
            線程調度
                常識:一個單核的CPU,在同一時刻只能執行一條線程
                線程調度:CPU在多個線程之間進行快速切換(併發的由來)
                線程調度分類:
                    分時調度:每個線程拼接分配CPU的時間
                    搶佔式調度:每個線程隨機分配CPU的時間
                Java進程中多個線程採取搶佔式調度
                
        3.創建新的線程方式一
            當我們運行一個Java程序時,就是一個Java進程
            這個進程中默認有至少兩個線程:
                第一個:main方法所在的線程,稱爲主線程
                第二個:gc線程(垃圾回收線程)
            如何創建一個新的線程呢???
                Java中提供了一個代表線程的類,稱爲Thread類
            API的描述:
                一種方法是將類聲明爲Thread子類
                該子類應重寫Thread類的run方法
                接下來可以分配並啓動該子類的實例
            a.定義一個類繼承Thread類
            b.重寫run方法(就是寫線程任務代碼的地方)
            c.創建子類對象(就是一個線程對象)
            d.啓動線程(調用start方法即可)
//1.繼承
public class MyThread extends Thread {
    //2.重寫run
    @Override
    public void run() {
        //1.喫飯
        for (int i = 0; i < 20; i++) {
            System.out.println("喫飯"+i);
        }
    }
}

public class TestDemo {
    public static void main(String[] args) {
        //3.創建線程對象
        MyThread mt = new MyThread();
        //4.啓動線程
        mt.start();
        //2.聽歌
        for (int i = 0; i < 20; i++) {
            System.out.println("聽歌"+i);
        }
    }
}

總結:
    -[] 能夠辨別程序中異常和錯誤的區別
    -[] 說出異常的分類
        Throwable
            Error
            Exception
                編譯時異常
                運行時異常
    -[] 說出虛擬機處理異常的方式
        中斷處理
        a.停止運行
        b.直接打印
    -[] 列舉出常見的三個運行期異常
        ArrayIndexOutOfBoundsException
        NullPoiinterException
        ClassCastException            
    -[] 能夠使用try...catch關鍵字處理異常********
    -[] 能夠使用throws關鍵字處理異常*********
    -[] 能夠自定義異常類
    -[] 能夠處理自定義異常類
    -[] 說出進程的概念********
    -[] 說出線程的概念********
    -[] 能夠理解併發與並行的區別*********
    -[] 能夠開啓新線程***************************

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章