Java程式設計基礎20——異常&IO(File類)

扎瓦發表於2019-01-19

1_異常(異常的概述和分類)

  • A:異常的概述

    • 異常就是Java程式在執行過程中出現的錯誤。
  • B:異常的分類

    • 通過API檢視Throwable
    • Error

      • 伺服器當機,資料庫崩潰等
    • Exception

C:異常的繼承體系

* Throwable
    * Error    
    * Exception
        * RuntimeException

2_異常(JVM預設是如何處理異常的)

  • A:JVM預設是如何處理異常的

    • main函式收到這個問題時,有兩種處理方式:
    • a:自己將該問題處理,然後繼續執行
    • b:自己沒有針對的處理方式,只有交給呼叫main的jvm來處理
    • jvm有一個預設的異常處理機制,就將該異常進行處理.
    • 並將該異常的名稱,異常的資訊.異常出現的位置列印在了控制檯上,同時將程式停止執行
  • B:案例演示

    • JVM預設如何處理異常
public class Demo1_Exception {
    public static void main(String[] args) {
//        demo1();
        Demo d = new Demo();
        int x = d.div(10, 0);        //new ArithmeticException(/ by zero)  除數是0,違反算數運演算法則
        System.out.println(x);
    }
    private static void demo1() { 
        int[] arr = {11,22,33,44,55};
//        arr = null;                    //NullPointerException            空指標異常
        System.out.println(arr[10]);    //ArrayIndexOutOfBoundsException    陣列索引越界異常
    }
}
class Demo{
    public int div(int a,int b) {
        return a / b;
    }
}

3_異常(try…catch的方式處理異常1)

  • A:異常處理的兩種方式

    • a:try…catch…finally

      • try catch
      • try catch finally
      • try finally
    • b:throws
  • B:try…catch處理異常的基本格式

    • try…catch…finally
  • C:案例演示

    • try…catch的方式處理1個異常
public class Demo2_Exception {
    /* try:用來檢測異常
     catch:用來捕獲異常的
     finally:釋放資源
     當通過trycatch將異常處理,程式繼續向下執行*/
    public static void main(String[] args) {
        Demo2 d = new Demo2();
        try {
            int x = d.div(10, 0);
            System.out.println(x);
        }catch(ArithmeticException a) {
            System.out.println("出錯了,除數為0了");
        }
        System.out.println("----------");
    }
}
class Demo2{
    public int div(int a,int b) {
        return a / b;
    }
}

4_異常(try…catch的方式處理異常2)

  • A:案例演示

    • try…catch的方式處理多個異常
    • JDK7以後處理多個異常的方式及注意事項
public class Demo3_Exception {
//安卓:客戶端開發,如何處理異常?try{}catch(Exception e) {}
//JavaEE:服務端開發,一般都是底層開發,從底層向上拋
    public static void main(String[] args) {
//        demo1();
        int a = 10;
        int b = 0;
        int[] arr = {11,22,33,44,55};
        //JdK7如何處理多個異常
        try {
            System.out.println(a / b);
            System.out.println(arr[10]);
        } catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
            System.out.println("出錯了");
        } 
    }

    private static void demo1() {
        int a = 10;
        int b = 0;
        int[] arr = {11,22,33,44,55};
        try {
            System.out.println(a / b);
            System.out.println(arr[10]);
            arr = null;
            System.out.println(arr[0]);
        } catch (ArithmeticException e) {
            System.out.println("除數不能為零");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("索引越界了");
        } catch (Exception e) {                //Exception e = new NullPointerException();
            System.out.println("出錯了");
        }
        System.out.println("over");
    }
}

5_異常(編譯期異常和執行期異常的區別)

  • A:編譯期異常和執行期異常的區別

    • Java中的異常被分為兩大類:編譯時異常和執行時異常。
    • 所有的RuntimeException類及其子類的例項被稱為執行時異常,其他的異常就是編譯時異常
    • 編譯時異常

      • Java程式必須顯示處理,否則程式就會發生錯誤,無法通過編譯
    • 執行時異常

      • 無需顯示處理,也可以和編譯時異常一樣處理
  • B:案例演示

    • 編譯期異常和執行期異常的區別
import java.io.FileInputStream;
public class Demo4_Exception {
/*
編譯時異常:也叫健壯性異常,不處理編譯通不過。
執行時異常:就是程式設計師所犯的錯誤,需要回來修改程式碼。
*/    
    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("xxx.txt");
        } catch (Exception e) {
    
        }
    }
}

6_異常(Throwable的幾個常見方法)

  • A:Throwable的幾個常見方法

    • a:getMessage()

      • 獲取異常資訊,返回字串。
    • b:toString()

      • 獲取異常類名和異常資訊,返回字串。
    • c:printStackTrace()

      • 獲取異常類名和異常資訊,以及異常出現在程式中的位置。返回值void。
  • B:案例演示

    • Throwable的幾個常見方法的基本使用
public class Demo5_throwable {
    public static void main(String[] args) {
        try {
            System.out.println(1/0);
        } catch (Exception e) {        //Exception e = new ArithmeticException(" / by zero");
//            System.out.println(e.getMessage());            //獲取異常資訊
            System.out.println(e);                        //呼叫toString方法,列印異常類名和異常資訊
            e.printStackTrace();                        //jvm預設就用這種方式處理異常
        }
    }
}

7_異常(throws的方式處理異常)

  • A:throws的方式處理異常

    • 定義功能方法時,需要把出現的問題暴露出來讓呼叫者去處理。
    • 那麼就通過throws在方法上標識。
  • B:案例演示

    • 舉例分別演示編譯時異常和執行時異常的丟擲

public class Demo6_Exception {
//編譯時異常的丟擲必須對其進行處理
//執行時異常的丟擲可以處理也可以不處理

    public static void main(String[] args) throws Exception {
        Person p = new Person();
        p.setAge(-17);
        System.out.println(p.getAge());
    }
}

class Person{
    private String name;
    private int age;
    public Person() {
        super();
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) throws RuntimeException {
        if(age > 0 && age <= 150) {
            this.age = age;
        }else {
            throw new RuntimeException("年齡非法");
//            System.out.println("請回火星吧");
        }
    }
}

8_異常(throw的概述以及和throws的區別)

  • A:throw的概述

    • 在功能方法內部出現某種情況,程式不能繼續執行,需要進行跳轉時,就用throw把異常物件丟擲。
  • B:案例演示

    • 分別演示編譯時異常物件和執行時異常物件的丟擲
  • C:throws和throw的區別

    • a:throws

      • 用在方法宣告後面,跟的是異常類名
      • 可以跟多個異常類名,用逗號隔開
      • 表示丟擲異常,由該方法的呼叫者來處理
    • b:throw

      • 用在方法體內,跟的是異常物件名
      • 只能丟擲一個異常物件名
      • 表示丟擲異常,由方法體內的語句處理

9_異常(finally關鍵字的特點及作用)

  • A:finally的特點

    • 被finally控制的語句體一定會執行
    • 特殊情況:在執行到finally之前jvm退出了(比如System.exit(0))
  • B:finally的作用

    • 用於釋放資源,在IO流操作和資料庫操作中會見到
  • C:案例演示

    • finally關鍵字的特點及作用
public static void main(String[] args) {
        try {
            System.out.println(10/0);
        } catch (Exception e) {
            System.out.println("除數為零了");
            System.exit(0);            //退出jvm虛擬機器
            return;
        } finally {
            System.out.println("看看我執行了嗎");
        }        
    }

10_異常(finally關鍵字的面試題)

  • A:面試題1

    • final,finally和finalize的區別

      • final可以修飾類不能被繼承,修飾方法不能被重寫,修飾變數只能賦值一次
      • finally是try語句中的一個語句體,不能單獨使用,用來釋放資源
      • finalize是一個方法,當垃圾回收器確定不存在該物件的更多引用時,由物件的垃圾回收器呼叫此方法。
  • B:面試題2

    • 如果catch裡面有return語句,請問finally的程式碼還會執行嗎?如果會,請問是在return前還是return後。
public class Demo8_test {
    public static void main(String[] args) {
        Demo3 d = new Demo3();
        System.out.println(d.method());
    }
}
class Demo3 {
    public int method() {
        int x = 10;
        try {
            x = 20;
            System.out.println(1/0);
            return x;
        } catch (Exception e) {
            x = 30;
            return x;
        } finally {
            x = 40;
        }
    }
}

11_異常(自定義異常概述和基本使用)

  • A:為什麼需要自定義異常

    • 舉例:人的年齡
  • B:自定義異常概述

    • 繼承自Exception
    • 繼承自RuntimeException
  • C:案例演示

    • 自定義異常的基本使用
class AgeOutOfBoundsException extends RuntimeException {
    public AgeOutOfBoundsException() {
        super();        
    }

    public AgeOutOfBoundsException(String message) {
        super(message);    
    }
}
    public void setAge(int age) throws AgeOutOfBoundsException {
        if(age > 0 && age <= 150) {
            this.age = age;
        }else {
            throw new AgeOutOfBoundsException("年齡非法");
        }
    }

12_異常(異常的注意事項及如何使用異常處理)

  • A:異常注意事項

    • a:子類重寫父類方法時,子類的方法必須丟擲相同的異常或父類異常的子類。(父親壞了,兒子不能比父親更壞)
    • b:如果父類丟擲了多個異常,子類重寫父類時,只能丟擲相同的異常或者是他的子集,子類不能丟擲父類沒有的異常
    • c:如果被重寫的方法沒有異常丟擲,那麼子類的方法絕對不可以丟擲異常,如果子類方法內有異常發生,那麼子類只能try,不能throws
  • B:如何使用異常處理

    • 原則:如果該功能內部可以將問題處理,用try,如果處理不了,交由呼叫者處理,這是用throws
    • 區別:

      • 後續程式需要繼續執行就try
      • 後續程式不需要繼續執行就throws
    • 如果JDK沒有提供對應的異常,需要自定義異常。

13_異常(練習)

  • 鍵盤錄入一個int型別的整數,對其求二進位制表現形式

    • 如果錄入的整數過大,給予提示,錄入的整數過大請重新錄入一個整數BigInteger
    • 如果錄入的是小數,給予提示,錄入的是小數,請重新錄入一個整數
    • 如果錄入的是其他字元,給予提示,錄入的是非法字元,請重新錄入一個整數
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Demo10_test {    
/** 分析
     * 1.建立鍵盤錄入物件
     * 2.將鍵盤錄入的結果儲存在String型別的字串中,儲存int型別中,如果有不符合條件的直接報錯,無法進行後續判斷
     * 3.是鍵盤錄入的結果轉換成int型別的資料,是正確的還是錯誤的。
     * 4.正確的直接轉換
     * 5.錯誤的要對應的判斷
     * */ 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入一個整數:");
        while(true) {
            String line = sc.nextLine();                    //將鍵盤錄入的結果儲存在line中
            try {
                int num = Integer.parseInt(line);                //將字串轉換為整數
                System.out.println(Integer.toBinaryString(num));//將整數轉換為二進位制
                break;                                            //跳出迴圈
            } catch (Exception e) {
                try {
                    new BigInteger(line);
                    System.out.println("錄入錯誤,您錄入的是一個過大的整數,請重新輸入:");    
                } catch (Exception e2) {                        //Alt + Shift + z
                    try {
                        new BigDecimal(line);
                        System.out.println("錄入錯誤,您錄入的是一個小數,請重新輸入:");
                    } catch (Exception e3) {
                        System.out.println("錄入錯誤,您錄入的是非法字元,請重新輸入:");
                    }
                }
            }
        }
//        BigInteger big = new BigInteger("123");
    }
}

14_File類(File類的概述和構造方法)

  • A:File類的概述

    • File更應該叫做一個路徑

      • 檔案路徑或者資料夾路徑
      • 路徑分為絕對路徑和相對路徑
      • 絕對路徑是一個固定的路徑,從碟符開始
      • 相對路徑相對於某個位置,在eclipse下是指當前專案下,在dos下
    • 檢視API指的是當前路徑
    • 檔案和目錄路徑名的抽象表示形式
  • B:構造方法

    • File(String pathname):根據一個路徑得到File物件
    • File(String parent, String child):根據一個目錄和一個子檔案/目錄得到File物件
    • File(File parent, String child):根據一個父File物件和一個子檔案/目錄得到File物件
  • C:案例演示

    • File類的構造方法
import java.io.File;
public class Demo1_File {
    public static void main(String[] args) {
//        demo1();
//        demo2();
        File parent = new File("C:\Users\albert\Desktop\JavaGuide-master\Java相關");
        String child = "ArrayList.md";
        File file = new File(parent, child);
        System.out.println(file.exists());
        System.out.println(parent.exists());
    }

    private static void demo2() {
        String parent = "C:\Users\albert\Desktop\JavaGuide-master\Java相關";
        String child = "ArrayList.md";
        File file = new File(parent,child);
        System.out.println(file.exists());
    }

    private static void demo1() {
        File file = new File("C:\Users\albert\Desktop\JavaGuide-master\Java相關");
        System.out.println(file.exists());
        
        File file2 = new File("xxx.txt");
        System.out.println(file2.exists());
    }
}

15_File類(File類的建立功能)

  • A:建立功能

    • public boolean createNewFile():建立檔案 如果存在這樣的檔案,就不建立了
    • public boolean mkdir():建立資料夾 如果存在這樣的資料夾,就不建立了
    • public boolean mkdirs():建立資料夾,如果父資料夾不存在,會幫你建立出來
  • B:案例演示

    • File類的建立功能
    • 注意事項:

      • 如果你建立檔案或者資料夾忘了寫碟符路徑,那麼,預設在專案路徑下。
import java.io.File;
import java.io.IOException;
public class Demo2_FileMethod {
    public static void main(String[] args) throws IOException {
//        demo1();
        File dir1 = new File("aaa");
        System.out.println(dir1.mkdir());
        
        File dir2 = new File("bbb.txt");
        System.out.println(dir2.mkdir());
        
        File dir3 = new File("ccc\ddd");
        System.out.println(dir3.mkdirs());                    //建立多級目錄
    }

    private static void demo1() throws IOException {
        File file = new File("yyy.txt");                    //建立檔案
        System.out.println(file.createNewFile());            //如果沒喲就建立,返回true
        
        File file2 = new File("zzz");
        System.out.println(file2.createNewFile());
    }
}

16_File類(File類的重新命名和刪除功能)

  • A:重新命名和刪除功能

    • public boolean renameTo(File dest):把檔案重新命名為指定的檔案路徑
    • public boolean delete():刪除檔案或者資料夾
  • B:重新命名注意事項

    • 如果路徑名相同,就是改名。
    • 如果路徑名不同,就是改名並剪下。
  • C:刪除注意事項:

    • Java中的刪除不走回收站。
    • 要刪除一個資料夾,請注意該資料夾內不能包含檔案或者資料夾
import java.io.File;
public class Demo3_FileMethod {
    public static void main(String[] args) {
//        demo1();
        File file1 = new File("yyy.txt");
        System.out.println(file1.delete());
        
        File file2 = new File("aaa");
        System.out.println(file2.delete());
        
        File file3 = new File("ccc");            //被刪除的檔案必須為空
        System.out.println(file3.delete());
    }

    private static void demo1() {
        File file1 = new File("ooo.txt");
        File file2 = new File("D:\xxx.txt");
        System.out.println(file1.renameTo(file2));
    }
}

17_File類(File類的判斷功能)

  • A:判斷功能

    • public boolean isDirectory():判斷是否是目錄
    • public boolean isFile():判斷是否是檔案
    • public boolean exists():判斷是否存在
    • public boolean canRead():判斷是否可讀
    • public boolean canWrite():判斷是否可寫
    • public boolean isHidden():判斷是否隱藏
  • B:案例演示

    • File類的判斷功能
import java.io.File;
public class Demo4_FileMethod {
    public static void main(String[] args) {
//        demo1();
        File file = new File("zzz");
        file.setReadable(false);                //windows認為所有的檔案都是可讀的
        System.out.println(file.canRead());
        
        file.setWritable(true);
        System.out.println(file.canWrite());    //windows系統可以設定為不可寫
        
        File file2 = new File("lalala.txt");
        System.out.println(file2.isHidden());    //判斷是否是隱藏檔案
    }

    private static void demo1() {
        File dir1 = new File("ccc");
        System.out.println(dir1.isDirectory());        //判斷是否是資料夾
        
        File dir2 = new File("zzz");
        System.out.println(dir2.isDirectory());
        
        System.out.println(dir1.isFile());            //判斷是否是檔案
        System.out.println(dir2.isFile());
    }
}

18_File類(File類的獲取功能)

  • A:獲取功能

    • public String getAbsolutePath():獲取絕對路徑
    • public String getPath():獲取路徑
    • public String getName():獲取名稱
    • public long length():獲取長度。位元組數
    • public long lastModified():獲取最後一次的修改時間,毫秒值
    • public String[] list():獲取指定目錄下的所有檔案或者資料夾的名稱陣列
    • public File[] listFiles():獲取指定目錄下的所有檔案或者資料夾的File陣列
  • B:案例演示

    • File類的獲取功能
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo5_FileMethod {
    public static void main(String[] args) {
//        demo1();
        File dir = new File("E:\Javawork\JavaSE_File");
        String[] arr = dir.list();                    //僅為了獲取檔名
        for (String string : arr) {
            System.out.println(string);
        }
        
        File[] subFiles = dir.listFiles();
        for (File file : subFiles) {                //獲取檔案物件
            System.out.println(file);
        }
    }

    private static void demo1() {
        File file1 = new File("ccc.txt");
        File file2 = new File("E:\Javawork\JavaSE_File\ccc.txt");
//        System.out.println(file1.getAbsolutePath());        //獲取絕對路徑
//        System.out.println(file2.getAbsolutePath());
        
//        System.out.println(file1.getPath());                //獲取構造方法中傳入的路徑
//        System.out.println(file2.getPath());
        
//        System.out.println(file1.getName());
//        System.out.println(file2.getName());                //獲取檔案或資料夾的名稱
        
//        System.out.println(file1.length());
//        System.out.println(file2.length());
        
        Date d = new Date(file1.lastModified());            //檔案的最後修改時間
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        System.out.println(sdf.format(d));
        System.out.println(file2.lastModified());
    }
}

19_File類(輸出指定目錄下指定字尾的檔名)

  • A:案例演示

    • 需求:判斷E盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出該檔名稱
import java.io.File;
public class Demo6_test {
    /** A:案例演示
    * 需求:判斷E盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出該檔名稱*/
    public static void main(String[] args) {
        File dir = new File("E:\");
        /*String[] arr = dir.list();                //獲取E盤下所有檔案及資料夾
        for (String string : arr) {
            if(string.endsWith(".jpg")) {
                System.out.println(string);
            }
        }*/
        
        File[] subFiles = dir.listFiles();        //獲取E盤下所有的檔案和資料夾物件
        for (File subFile : subFiles) {
            if(subFile.isFile() && subFile.getName().endsWith(".jpg")) {
                System.out.println(subFile);
            }
        }
    }
}

20_File類(檔名稱過濾器的概述及使用)

  • A:檔名稱過濾器的概述

    • public String[] list(FilenameFilter filter)
    • public File[] listFiles(FileFilter filter)
  • B:檔名稱過濾器的使用

    • 需求:判斷E盤目錄下是否有字尾名為.jpg的檔案,如果有,就輸出該檔名稱
  • C:原始碼分析

    • 帶檔名稱過濾器的list()方法的原始碼
        File dir = new File("E:\");
        String[] arr = dir.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
//                System.out.println(dir);
//                System.out.println(name);
                File file = new File(dir, name);
                return file.isFile() && file.getName().endsWith(".jpg");
            }
        });
        for (String string : arr) {
            System.out.println(string);
        }

相關文章