Java:異常

JVM 處理方式
1.把異常的名稱,錯(cuò)誤原因及異常出現(xiàn)的位置等信息輸出在了控制臺(tái)
2.程序停止執(zhí)行

1.異常體系

2.編譯時(shí)異常和運(yùn)行時(shí)異常

  • 編譯時(shí)異常

    • 都是Exception類及其子類
    • 必須顯示處理,否則程序就會(huì)發(fā)生錯(cuò)誤,無(wú)法通過(guò)編譯
  • 運(yùn)行時(shí)異常

    • 都是RuntimeException類及其子類
    • 無(wú)需顯示處理,也可以和編譯時(shí)異常一樣處理

3:throws方式處理異常

  • 定義格式

    public void 方法() throws 異常類名 {
        
    }
    
  • 示例代碼

    public class ExceptionDemo {
        public static void main(String[] args) throws ParseException{
            System.out.println("開始");
    //        method();
              method2();
    
            System.out.println("結(jié)束");
        }
    
        //編譯時(shí)異常
        public static void method2() throws ParseException {
            String s = "2048-08-09";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date d = sdf.parse(s);
            System.out.println(d);
        }
    
        //運(yùn)行時(shí)異常
        public static void method() throws ArrayIndexOutOfBoundsException {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]);
        }
    }
    
    • 這個(gè)throws格式是跟在方法的括號(hào)后面的
    • 編譯時(shí)異常必須要進(jìn)行處理,兩種處理方案:try...catch …或者 throws,如果采用 throws 這種方案,在方法上進(jìn)行顯示聲明,將來(lái)誰(shuí)調(diào)用這個(gè)方法誰(shuí)處理
    • 運(yùn)行時(shí)異常因?yàn)樵谶\(yùn)行時(shí)才會(huì)發(fā)生,所以在方法后面可以不寫,運(yùn)行時(shí)出現(xiàn)異常默認(rèn)交給jvm處理

4:throw拋出異常

throw new 異常();

  • 這個(gè)格式是在方法內(nèi)的,表示當(dāng)前代碼手動(dòng)拋出一個(gè)異常,下面的代碼不用再執(zhí)行了

  • throws和throw的區(qū)別

    throws throw
    用在方法聲明后面,跟的是異常類名 用在方法體內(nèi),跟的是異常對(duì)象名
    表示聲明異常,調(diào)用該方法有可能會(huì)出現(xiàn)這樣的異常 表示手動(dòng)拋出異常對(duì)象,由方法體內(nèi)的語(yǔ)句處理
  • 示例代碼

    public class ExceptionDemo8 {
        public static void main(String[] args) {
            //int [] arr = {1,2,3,4,5};
            int [] arr = null;
            printArr(arr);//就會(huì) 接收到一個(gè)異常.
                            //我們還需要自己處理一下異常.
        }
    
        private static void printArr(int[] arr) {
            if(arr == null){
                //調(diào)用者知道成功打印了嗎?
                //System.out.println("參數(shù)不能為null");
                throw new NullPointerException(); //當(dāng)參數(shù)為null的時(shí)候
                                                //手動(dòng)創(chuàng)建了一個(gè)異常對(duì)象,拋給了調(diào)用者,產(chǎn)生了一個(gè)異常
            }else{
                for (int i = 0; i < arr.length; i++) {
                    System.out.println(arr[i]);
                }
            }
        }
    
    }
    

5 try-catch方式處理異常

  • 定義格式

    try {
      可能出現(xiàn)異常的代碼;
    } catch(異常類名 變量名) {
      異常的處理代碼;
    }
    
  • 執(zhí)行流程

    • 程序從 try 里面的代碼開始執(zhí)行
    • 出現(xiàn)異常,就會(huì)跳轉(zhuǎn)到對(duì)應(yīng)的 catch 里面去執(zhí)行
    • 執(zhí)行完畢之后,程序還可以繼續(xù)往下執(zhí)行
  • 示例代碼

    public class ExceptionDemo01 {
        public static void main(String[] args) {
            System.out.println("開始");
            method();
            System.out.println("結(jié)束");
        }
    
        public static void method() {
            try {
                int[] arr = {1, 2, 3};
                System.out.println(arr[3]);
                System.out.println("這里能夠訪問(wèn)到嗎");
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("你訪問(wèn)的數(shù)組索引不存在,請(qǐng)回去修改為正確的索引");
            }
        }
    }
    
  • 注意

    1. 如果 try 中沒(méi)有遇到問(wèn)題,怎么執(zhí)行?
      會(huì)把try中所有的代碼全部執(zhí)行完畢,不會(huì)執(zhí)行catch里面的代碼

    2. 如果 try 中遇到了問(wèn)題,那么 try 下面的代碼還會(huì)執(zhí)行嗎?
      那么直接跳轉(zhuǎn)到對(duì)應(yīng)的catch語(yǔ)句中,try下面的代碼就不會(huì)再執(zhí)行了
      當(dāng)catch里面的語(yǔ)句全部執(zhí)行完畢,表示整個(gè)體系全部執(zhí)行完全,繼續(xù)執(zhí)行下面的代碼

    3. 如果出現(xiàn)的問(wèn)題沒(méi)有被捕獲,那么程序如何運(yùn)行?
      那么try...catch就相當(dāng)于沒(méi)有寫.那么也就是自己沒(méi)有處理.
      默認(rèn)交給虛擬機(jī)處理.

    4. 同時(shí)有可能出現(xiàn)多個(gè)異常怎么處理?
      出現(xiàn)多個(gè)異常,那么就寫多個(gè)catch就可以了.
      注意點(diǎn):如果多個(gè)異常之間存在子父類關(guān)系.那么父類一定要寫在下面

4.8 Throwable成員方法(應(yīng)用)

  • 常用方法

    方法名 說(shuō)明
    public String getMessage() 返回此 throwable 的詳細(xì)消息字符串
    public String toString() 返回此可拋出的簡(jiǎn)短描述
    public void printStackTrace() 把異常的錯(cuò)誤信息輸出在控制臺(tái)
  • 示例代碼

   public static void main(String[] args) {
        System.out.println("開始");
        method();
        System.out.println("結(jié)束");
    }

    public static void method() {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]); //new ArrayIndexOutOfBoundsException();
            System.out.println("這里能夠訪問(wèn)到嗎");
        } catch (ArrayIndexOutOfBoundsException e) { //new ArrayIndexOutOfBoundsException();
            // 返回此 throwable 的詳細(xì)消息字符串
            System.out.println(e.getMessage());

            // 返回此可拋出的簡(jiǎn)短描述
            System.out.println(e.toString());

            //把異常的錯(cuò)誤信息輸出在控制臺(tái)
            e.printStackTrace();

        }
    }

9:自定義異常

  • 實(shí)現(xiàn)步驟

    1. 定義異常類
    2. 寫繼承關(guān)系
    3. 提供空參構(gòu)造
    4. 提供帶參構(gòu)造
  • 代碼實(shí)現(xiàn)

    異常類

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

    學(xué)生類

    public class Student {
        private String name;
        private int age;
    
        public Student() {
        }
    
        public Student(String name, int age) {
            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) {
            if(age >= 18 && age <= 25){
                this.age = age;
            }else{
                //如果Java中提供的異常不能滿足我們的需求,我們可以使用自定義的異常
                throw new AgeOutOfBoundsException("年齡超出了范圍");
            }
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    

    測(cè)試類

    public class ExceptionDemo12 {
        public static void main(String[] args) {
            // 鍵盤錄入學(xué)生的姓名和年齡,其中年齡為 18 - 25歲,
            // 超出這個(gè)范圍是異常數(shù)據(jù)不能賦值.需要重新錄入,一直錄到正確為止。
    
            Student s = new Student();
    
            Scanner sc = new Scanner(System.in);
            System.out.println("請(qǐng)輸入姓名");
            String name = sc.nextLine();
            s.setName(name);
           while(true){
               System.out.println("請(qǐng)輸入年齡");
               String ageStr = sc.nextLine();
               try {
                   int age = Integer.parseInt(ageStr);
                   s.setAge(age);
                   break;
               } catch (NumberFormatException e) {
                   System.out.println("請(qǐng)輸入一個(gè)整數(shù)");
                   continue;
               } catch (AgeOutOfBoundsException e) {
                   System.out.println(e.toString());
                   System.out.println("請(qǐng)輸入一個(gè)符合范圍的年齡");
                   continue;
               }
               /*if(age >= 18 && age <=25){
                   s.setAge(age);
                   break;
               }else{
                   System.out.println("請(qǐng)輸入符合要求的年齡");
                   continue;
               }*/
           }
            System.out.println(s);
    
        }
    }
    

10:finally

用來(lái)創(chuàng)建在 try 代碼塊后面執(zhí)行的代碼塊。無(wú)論是否發(fā)生異常,finally 代碼塊中的代碼總會(huì)被執(zhí)行。在 finally 代碼塊中,可以運(yùn)行清理類型等收尾善后性質(zhì)的語(yǔ)句

try{
  // 程序代碼
}catch(異常類型1 異常的變量名1){
  // 程序代碼
}catch(異常類型2 異常的變量名2){
  // 程序代碼
}finally{
  // 程序代碼
}
  • 實(shí)例
public class ExcepTest{
  public static void main(String args[]){
    int a[] = new int[2];
    try{
       System.out.println("Access element three :" + a[3]);
    }catch(ArrayIndexOutOfBoundsException e){
       System.out.println("Exception thrown  :" + e);
    }
    finally{
       a[0] = 6;
       System.out.println("First element value: " +a[0]);
       System.out.println("The finally statement is executed");
    }
  }
}
  • 注意
    • catch 不能獨(dú)立于 try 存在。
    • 在 try/catch 后面添加 finally 塊并非強(qiáng)制性要求的。
    • try 代碼后不能既沒(méi) catch 塊也沒(méi) finally 塊。
    • try, catch, finally 塊之間不能添加任何代碼。

11:try-with-resources

  • DK7 之后,Java 新增的 try-with-resource 語(yǔ)法糖來(lái)打開資源,并且可以在語(yǔ)句執(zhí)行完畢后確保每個(gè)資源都被自動(dòng)關(guān)閉 。

  • JDK7 之前所有被打開的系統(tǒng)資源,比如流、文件或者 Socket 連接等,都需要被開發(fā)者手動(dòng)關(guān)閉,否則將會(huì)造成資源泄露。

try (resource declaration) {
  // 使用的資源
} catch (ExceptionType e1) {
  // 異常塊
}

try 用于聲明和實(shí)例化資源,catch 用于處理關(guān)閉資源時(shí)可能引發(fā)的所有異常。

public class RunoobTest {

    public static void main(String[] args) {
    String line;
        try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
            while ((line = br.readLine()) != null) {
                System.out.println("Line =>"+line);
            }
        } catch (IOException e) {
            System.out.println("IOException in try block =>" + e.getMessage());
        }
    }
}

我們實(shí)例一個(gè) BufferedReader 對(duì)象從 test.txt 文件中讀取數(shù)據(jù)。
在 try-with-resources 語(yǔ)句中聲明和實(shí)例化 BufferedReader 對(duì)象,執(zhí)行完畢后實(shí)例資源,不需要考慮 try 語(yǔ)句是正常執(zhí)行還是拋出異常。
如果發(fā)生異常,可以使用 catch 來(lái)處理異常。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 【傳智播客.黑馬程序員訓(xùn)練營(yíng)成都中心】 Java異常淺析 前言 異常二字,從字面上來(lái)理解就是:不正常。程序中的異常...
    OpenCoder閱讀 455評(píng)論 1 1
  • 異常 概念 異常是程序運(yùn)行過(guò)程中可能發(fā)生的一類事件。 當(dāng)方法中發(fā)生錯(cuò)誤時(shí),該方法會(huì)創(chuàng)建一個(gè)對(duì)象——異常對(duì)象——并將...
    FoxLayla閱讀 421評(píng)論 0 0
  • 第一節(jié):異常分類 示例圖 ThrowableErrorException虛擬機(jī)錯(cuò)誤內(nèi)存溢出線程死鎖檢查異常非檢查異...
    張學(xué)周閱讀 121評(píng)論 0 0
  • 1、什么是異常 異常:不是編譯錯(cuò)誤;編譯錯(cuò)誤是運(yùn)行之前檢查出來(lái)的; 異常是【程序運(yùn)行時(shí)】出現(xiàn)的不正?,F(xiàn)象。 2、異...
    XLMN閱讀 220評(píng)論 0 0
  • 詳解Java異常 異常的定義: 異常指不期而至的各種狀況,如:文件找不到、網(wǎng)絡(luò)連接失敗、非法參數(shù)等。異常是一個(gè)事件...
    測(cè)試開發(fā)Kevin閱讀 185評(píng)論 0 7

友情鏈接更多精彩內(nèi)容