Java 第十三天(純乾貨)(帶你14天瞭解並掌握Java SE)

今日內容

  • 異常
  • File類
  • IO(字節流) input : 輸入 --> 讀取 Output : 輸出 --> 寫出

01. 異常的概述和繼承體系

  • 異常的概念:
異常:異常指的就是不正常

        簡單理解就是我們程序所發生的錯誤。

例如:當出現異常的運算條件時,拋出此異常。例如,一個整數“除以零”時,拋出此類的一個實例。
  • 常見的異常有:
ArrayIndexOutofboundsException
StringIndexOutofboundsException
ConcurrentModificationException
ClassCastException
NoSuchElementException
  • 異常的體系的介紹:
Throwable 類是 Java 語言中所有錯誤或異常的超類。

Error 是 Throwable 的子類,用於指示合理的應用程序不應該試圖捕獲的嚴重問題。
    也就是說針對程序發生了Error的情況,Java程序本身是無能爲力的,比如說:硬件層面的問題,內存不足等。
    所以,針對Error的問題我們不處理。

Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件。 
    也就是說針對程序發生了Exception的情況,是我們需要處理的問題。
  • Exception的分類:
    1. RuntimeException: 運行時異常: 編譯通過了,運行時出現的錯誤
            如果出現的運行時異常,就是我們程序員自身所發生的錯誤,是需要回頭修改源代碼的

                int[] arr = null;
                System.out.println(arr[0]);

2. !RuntimeException:
        編譯時異常: 編譯器在編譯的過程中,檢測到某段代碼可能會發生怎樣的問題
                        這時候需要我們程序員對代碼進行異常的【預】處理,否則編譯是一直失敗的
                        FileReader fr = new FileReader("D:\\abc.txt");

        注意:語法錯誤不是編譯時異常

02. JVM針對異常的默認處理方式

  • 異常有哪幾種處理方式?
  • jvm默認是如何處理異常的?
總結:
    1. 異常分類兩種處理方式:

            A. 問題很小,自己可以處理
                    try..catch

            B. 問題很大,自己處理不了
                    【拋給上一級】

    2.  jvm默認選擇拋出異常的方式, 拋給調用者.

            問題拋給main方法, 主方法的調用者是jvm, jvm接收到異常之後, 就將異常信息輸出在了控制檯.

                並且強制的結束程序運行。

03. 異常處理方案try…catch

  • 什麼情況下使用try..catch處理異常的方式
總結:
    1. 當發現問題可以自己解決的時候, 使用try..catch進行處理
            處理後,不會影響到後續代碼的繼續執行。

格式:

    try {
        需要包裹的是,有可能產生問題得代碼
    } catch(要抓捕的異常) {
        異常的處理方式
    }

try...catch的執行順序:

    首先會執行try語句中的代碼, 看被try包裹的代碼是否產生異常
            有 :  異常被catch進行捕獲, 然後走catch語句中的代碼
            沒有 : 程序繼續向下執行

    好處: 使用try..catch語句自己將問題處理掉之後, 不會影響到後續代碼的執行


    注意: 如果try語句中的代碼沒有發生異常, 那麼catch語句將不會執行.

            catch中只能捕獲()中聲明的異常, 如果想要捕獲所有的異常, 可以寫成父類 Exception


            alt + shift + z --> try..catch

            如果catch捕獲的是多個異常, 那麼大的異常需要放在最下面!!!

練習:

    需求: 編寫一段代碼, 要求代碼中會產生索引越界異常  
          並使用try...catch進行處理
    分析:
    第一步:定義數組
    第二步:在打印語句中訪問不存在的索引
    第三步:將可能發生問題的代碼用try包裹
    第四步:catch中捕獲IndexOutOfBoundsException
    第五步:對異常進行處理,並用printStackTrace打印出異常信息


異常對象的三個常用方法:

    toString() : 簡短描述

    getMessage() : 返回錯誤信息

    printStackTrace() : 返回錯誤的完整信息(錯誤的行數, 錯誤的異常, 錯誤的原因)  *** 

04. 編譯時異常和運行時異常的區別

  • 編譯時異常
  • 運行時異常
總結:
    1. 編譯時異常指的是編譯過程中, 編譯器檢測到某段代碼可能會出現怎樣的問題(文件找不到異常)(日期字符串輸入錯誤)
                我們必須對該問題進行【預】處理,否則編譯是不能通過的。

            public static void main(String[] args) throws ParseException {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                sdf.parse("2019年3月15日");
            }
    2. 編譯通過了,運行時出現的錯誤

05. 異常處理方案throws

  • 什麼情況下需要將異常拋出?
  • 案例演示: setAge賦值錯誤.
總結:
    1. 發現出現的問題,自己沒有一個合理的解決方案,就需要將錯誤拋給上級

代碼:

    public void setAge(int age) throws Exception {
        /*
         * 假如我們是Person類的編寫者,在編寫方法的時候,不清楚調用者傳入的是正確的還是錯誤的參數
         * 
         * 如果是錯誤的,需要讓調用者明白自己出錯了
         * 
         *      解決方案:將程序強制終止,並將錯誤信息輸出在控制檯
         * 
         *      throw : 用於拋出真正的異常對象
         * 
         *      throws :僅僅是對方法進行一個聲明, 告知調用者,此方法存在異常,調用時需要處理
         */
        if(age >= 0 && age <= 200){
            this.age = age;
        }else{
            throw new Exception("您的年齡非法了!");
        }
    }


思路:
        1. 如何拋出異常?

                throw new 異常對象("錯誤信息");

        2. 拋出異常對象之後呢?

                需要在方法上進行throws聲明,告知調用者此方法存在異常


        3. 調用者需要注意什麼?

                明確該方法存在異常, 需要對異常進行處理



結論: throw throws的區別是什麼?

            throw : 用於真正的拋出異常對象
            throws : 僅僅是對方法進行聲明,告知調用者此方法存在異常


注意: 
        如果拋出的異常是RuntimeException的話, 那麼就不需要throws的聲明.

06. File類的概述和構造方法

  • A:File類的概述和作用

    • a: File的概念
      • File類是文件和目錄路徑名的抽象表示形式
      • Java中把文件或者目錄(文件夾)都封裝成File對象

    總結:

    在java當中, 使用file類來表示(文件路徑)或者是(文件夾路徑)
    

    思路: 如果今後要操作硬盤中的某一個文件或者是文件夾的話, 那麼首先要考慮將要操作數據的路徑封裝成file對象.

  • B: File類的常用構造方法:

    • File(String pathname) :將一個字符串路徑封裝成File對象 ****
    • File(String parent,String child):傳入一個父級路徑和子級路徑
    • File(File parent,String child):傳入一個File類型的父級路徑和子級路徑 ****

07. File類的創建功能

  • boolean createNewFile():指定路徑不存在該文件時時創建文件,返回true,否則返回false
  • boolean mkdir():當指定的單級文件夾不存在時創建文件夾並返回true,否則返回false ****
  • boolean mkdirs():當指定的多級文件夾某一級文件夾不存在時,創建多級文件夾並返回true,否則返回false ****

08. File類的刪除功能

  • boolean delete():刪除文件或者刪除單級文件夾 ****
注意: delete方法在刪除文件的時候沒有問題

        delete方法在刪除文件夾
                    1. 單級文件夾    ,並且該文件夾必須是一個空的文件夾

        需求:鍵盤接受一個文件夾路徑,刪除該文件夾下所有的內容(遞歸)

總結:
    相對路徑: 相對於當前項目Project下
    絕對路徑: 從盤符的根目錄開始,一直只指向到具體的文件或文件夾

09. File類的判斷和獲取功能

  • 判斷功能(重點)****

    • boolean exists():判斷指定路徑的文件或文件夾是否存在
    • boolean isDirectory():判斷當前的目錄是否存在
    • boolean isFile():判斷當前路徑是否是一個文件
  • 獲取功能

    • String getAbsolutePath():獲取文件的絕對路徑,返回路徑的字符串 ****
    • String getPath():獲取File對象中封裝的路徑
    • String getName():獲取文件或文件夾的名稱 ****
  • 案例演示

    • 需求: 鍵盤錄入一個文件夾路徑
      • 如果錄入的文件不存在給出提示
      • 如果錄入的是一個文件,給出提示
      • 直到錄入了正確的文件夾路徑爲止, 程序終止

10. IO流的概述和分類

  • 什麼是IO流?
  • IO流的分類有哪些?
總結:
    1.
        I : input       -> 輸入       -> 讀取
        O : output      -> 輸出       -> 寫出
    2.

        流向分:

            1. 輸入流      -> 讀取數據
            2. 輸出流      -> 寫出數據


        類型分:

            字節流:
                    字節流可以稱之爲萬能流,因爲硬盤上任意一個文件都是以字節的形式存儲的

                    但是字節流在操作純文本文件的時候,有可能會出現一些亂碼的問題

            字符流:

                    如果今後操作的數據是純文本文件,建議使用字符流,避免亂碼的問題。


注意: IO流的抽象父類有哪些? 

    字節流:

        輸入流抽象父類:    IntpuStream
        輸出流抽象方法:  OuputStream

            小竅門:只要遇到類名是以xxxxStream爲結尾的,就說明是一個字節流

    字符流:

        輸入流抽象父類: Reader
        輸出流抽象父類: Writer

            小竅門:只要遇到類名是以Reader\Writer爲結尾的,就說明是一個字符流

11. FileOutputStream寫數據

  • 構造方法
  • 寫出數據使用的成員方法
總結:
    1.FileOutputStream(String name)     :  創建字節輸出流對象,將要關聯的文件以字符串給出
      FileOutputStream(File file)       :  創建字節輸出流對象,將要關聯的文件以File對象形式給出
    2.
        write(int b) 

代碼:
    IO流操作的基本步驟

    // 1. 創建字節輸出流對象
    // 輸出流關聯文件, 如果文件不存在, 則自動創建
    FileOutputStream fos = new FileOutputStream("a1.txt");

    // 2. 調用輸出流對象的方法寫出數據
    String s = "你可能說不出哪裏好, 但我就是想看你洗澡";
    fos.write(s.getBytes());


    // 3. 關閉流釋放資源!
    fos.close();
  • 轉ppt練習

12. FileOutputStream寫數據的三種方式.

  • public void write(int b):一次寫一個字節
  • public void write(byte[] b):一次寫一個字節數組
  • public void write(byte[] b,int off,int len):一次寫一個字節數組的一部分

13. FileOutputStream如何實現換行和追加寫數據

  • 如何實現數據的換行寫入?
  • 如何實現數據的尾部追加動作?
總結:
    1. 通過write方法將\r\n寫出去。-123、

            windowns : \r\n
            Linux : \n
            Mac : \r

            BufferedWriter -> newLine() -> 具有跨平臺性

    2. FileOutputStream(File file, boolean append) 
       FileOutputStream(String name, boolean append)    

        在構造方法的參數中, 傳入true, 開啓尾部追加

14. FileOutputStream寫數據加入異常處理

    FileOutputStream fos = null;
    try {
        // FileOutputStream fos = new FileOutputStream("d.txt");
        // fos = new FileOutputStream("z:\\d.txt");
        fos = new FileOutputStream("d.txt");
        fos.write("hello".getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            // 釋放資源
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

15. FileInputStream讀數據方式1一次讀取一個字節

  • 構造方法: FileInputStream(String name)
  • FileInputStream是通過哪個方法讀取數據的? 文件的末尾結束標記爲?
        * int read();
        * -1


        int i;

        while((i = fis.read()) != -1){

        }
  • 輸入和輸出的注意事項:
    • 輸出流操作文件, 如果文件不存在的話, 程序將會自動創建出一個
    • 輸入流讀取文件, 如果文件不存在, 則會拋出FileNotFoundException
        只能操的是文件,文件夾不能操作(拒絕訪問)
  • 轉ppt練習

16. FileInputStream讀數據方式2一次讀取一個字節數組.

  • 單個字節讀取效率如何?
  • 一次讀取一個字節數組的注意問題:
總結:
    1. 效率低下
    2. 一次如果讀取一個字節輸出,在轉換的過程中,如果沒有做好處理,就會出現數據的殘留現象。


        如何解決?


            // 1. 創建輸入流對象關聯數據源
            FileInputStream fis = new FileInputStream("aaa\\aaa.txt");
            // 2. 定義字節數組容器, 爲了提高讀取的效率
            byte[] bys = new byte[2];
            // 3. 定義臨時變量, 用於不斷的記錄read方法返回的有效字節個數
            int len = 0;
            // 4. 使用while循環不斷的讀取, 將read方法的返回值賦值給len
            while((len = fis.read(bys)) != -1){
                System.out.print(new String(bys, 0, len));
            }

            fis.close();

        依賴的方法:

            String(byte[] bytes, int offset, int length)    -> 構造方法

                將傳入的字節數組的一部分, 轉換成字符串

                bytes : 數據源
                offset : 起始的索引位置
                length : 轉換的個數

17. 字節流練習之複製文本文件.

  • 案例演示
  • 需求
拷貝文本文件
分析:
第一步: 創建輸入輸出流對象關聯數據源和數據目的
第二步: 定義字節數組,爲了提高效率
第三步: 將數據通過while循環不斷讀取到字節數組中
第四步: 將數據從字節數組中取出並寫出
第五步: 釋放資源


    // 1. 創建輸入流對象關聯數據源
    FileInputStream fis = new FileInputStream("窗裏窗外.txt");
    // 2. 創建輸出流對象關聯數據目的
    FileOutputStream fos = new FileOutputStream("copyText.txt");
    // 3. 使用java程序讀取數據源中的數據, 將讀取到的數據寫出到目標文件中
    byte[] bys = new byte[2048];

    int len = 0;

    while((len = fis.read(bys)) != -1){
        fos.write(bys, 0, len);
    }

    // 4. 關閉流釋放資源
    fis.close();
    fos.close();

18. 字節流練習之複製圖片

  • 案例演示
  • 5分鐘時間練習
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章