【JAVA】筆記(11)--- 精講異常(附枚舉);


異常:

一.什么是異常?異常處理機制有什么作用?

程序在執行時發生了我們不想發生的異常情況,這種情況叫做異常;java語言的特性之一 --- 健壯性的實現主要就是靠異常處理機制,當程序執行過程中發生了異常,系統將異常信息打印到控制台上,程序員根據異常信息就可以對程序進行進一步的修改,進而使程序更加的健壯;

注意:異常也是一種類,系統內置有很多不同的異常類對應不同的異常情況,我們同樣可以根據我們的需求來定義不同的異常類,來處理不同的異常情況;


二.異常的體系結構:

Throwablejava 中所有異常和錯誤的父類;

Error:程序員無法解決處理的錯誤情況(跟咱們沒關系,不用管);

Exception: 程序本身可以捕獲並且可以處理的異常情況;其中又分為運行時異常(RuntimeException)(又稱作不受檢異常)和編譯時異常(IOException)(又稱作受檢異常);

運行時異常:空指針異常,數組下標越界異常等;運行時異常我們一般不利用異常處理機制對其進行處理,解決辦法就是直接修改代碼;

編譯時異常:編譯時異常必須對其處理否則無法運行;


三.異常的抓拋:

1.異常的拋出:

如果程序在運行過程中執行某段代碼時發生了異常,那么系統(JVM)將會根據異常的類型,在異常發生處創建對應的異常類型的對象並拋出,拋出給程序的調用者,並且本段代碼所屬的方法體中異常后的代碼將不再運行;

注意:這里的異常有可能是系統內置的異常,也有可能是我們手動拋出(throw)的的異常(我們定義的異常類);

2.異常的抓取:

對於異常的發生,有倆種處理方式。第一種,調用“ try-catch-finally ”語句來抓取異常;第二種,上拋(throws)給異常發生的方法的調用者;


四.try-catch-finally:

1.try 方法體內放置可能會出現異常的代碼,如果異常發生,就會 new 出一個異常類,此異常類會與 catch 的異常類型進行匹配,匹配成功,執行 catch 方法體內的代碼(代碼一般為打印異常的基本信息或打印異常的詳細信息),匹配不成功,繼續匹配后面不同的 catch ,最后finally 方法體內的代碼最終一定會執行;

2.catch 多個異常類時,如果存在有繼承關系的類,一定要按從子類到父類的順序來 catch,因為如果第一個就 catch 最大的父類,那么可能執行的異常處理代碼並非我們想要的;如果無繼承關系,自然順序就無所謂了;

3.catch 方法內常用的異常處理方法:

1) 異常 . getMessage ( ) ;

// 返回值為異常的基本信息(throw new 異常 ( "返回值就是這里的字符串喲" ) );一般搭配 System . out . println ( ) 打印輸出信息;

2) 異常 . printSrackTrace ( ) ;

// 打印異常的詳細信息(堆棧追蹤信息),如:

com.bjpowernode.javase.day1.WeaponIndexOufException: 武器庫裝備已達上限,[Lcom.bjpowernode.javase.day1.Weapon;@7f31245a無法載入武器庫系統
	at com.bjpowernode.javase.day1.Army.addWeapon(Army.java:19)
	at com.bjpowernode.javase.day1.武器系統.main(武器系統.java:12)

//第一行為異常的基本信息;

//第二行為異常出現的地方(是第三行中的異常出現的果);

//第三行也就是最后一行,為第一個異常出現的地方,是第二行異常出現的因;

注意:異常的詳細信息要從下往上看,因為異常一般會存在因果關系;

4.finally 內的代碼優先級僅次於 System . exit ( 0 ) ;

//強制關閉退出 JVM ,所以 finally 內的代碼不會執行;即使try內有 return 語句,在try方法強制結束之前, 也會先執行 finally 內的代碼;

注意:

1)在 try 內聲明的變量,出了 try ,系統就不認識了,解決方法是在 try 外聲明變量並初始化,在 try 內賦值,所以要理解 try 內裝的是一個“ 模塊 ”,一個可能會出現異常的代碼模塊; 

2)try-catch-finally 也可以嵌套使用;

2)有 try ,必須有 finally / catch ,finally,catch 也不可以離開 try ;


五.throw -throws , try-catch-finally:

1.throw:手動拋出異常;一般這樣使用:

throw new XXXException("異常基本信息");//XXX代表是什么異常

2.throws:將“ 拋出的異常 ”捕獲並上交給方法的調用者;可以 throws 多個異常;一般這樣使用;

public void fangFa () throws XXXException{     //throws 的異常即為 方法體內 throw的異常
	throws new XXXException("異常基本信息");
}

3.對於“ 拋出(throw)的異常 ” 有倆種處理方式:

第一種,繼續上拋給方法的調用者,但其實並沒有真正的解決異常,如果一直上拋到 main 方法,都沒有 try catch 異常,main 方法會繼續上拋到JVM,然后程序到此結束;第二種,直接在異常發生的方法內進行try catch 處理;

那么在日常開發中,究竟該如何選擇倆者的處理方式呢?

1)第一種情況,異常發生方法為子類重寫父類的方法,然而對應的父類方法並沒有 throws 異常,所以子類中重寫的方法就不能選擇 throws 了,只能被迫在此方法中就地解決(try - catch);

2)第二種情況,異常發生的方法屬於被調用的方法,而且調用此方法的方法也是被調用的,上面還有更多更多的方法,一直到最初的執行方法,這種存在層層遞進,相互關聯的方法,一般選擇將所有異常都 thows 給最初的調用者方法,然后在此方法中統一對所有異常進行處理;

3)注意: try-catch 和 throws 在方法中不要同時使用,因為只要使用 try-catch 就已經將異常處理掉了,再 throws 沒有任何意義;


六.栗子老師:

public class pra {
    public static void main(String[] args) {
        People p=new People("王狗蛋");
        Food food=new Food("粑粑");
        try{
            p.eat(food);
        }catch (ErrorFoodException e){
            System.out.println(e.getMessage());
        }
    }
}
class People{
    String name;
    public People() {
    }
    public People(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void eat(Food food) throws ErrorFoodException{
        if ("粑粑".equals(food.foodName)){
            throw new ErrorFoodException("人不能吃"+food+"!");
            //System.out.println("sdsas"); 異常拋出后不能寫任何代碼,因為根本到不了,沒有意義
        }
        //if 語句外就不受異常拋出的影響了,因為系統認為 if() 語句不一定執行,所以if()外的代碼是有意義的
        System.out.println(name+"正在吃"+food);
    }
}
class Food{
    String foodName;
    public Food() {
    }
    public String getFoodName() {
        return foodName;
    }
    public void setFoodName(String foodName) {
        this.foodName = foodName;
    }
    public Food(String foodName) {
        this.foodName = foodName;
    }
    public String toString() {
        return foodName;
    }
}
class ErrorFoodException extends Exception{
    public ErrorFoodException() {
    }
    public ErrorFoodException(String message) {
        super(message);
    }
}

運行結果:
--------------------------------
人不能吃粑粑!

Process finished with exit code 0

枚舉:

1)概念:枚舉屬於引用數據類型,當結果為兩種情況的時候,用布爾型,當結果有3種或3種以上且可以一枚一枚將結果列舉出來,就需要定義枚舉來進行使用;

2)定義枚舉:enum    枚舉名   {     枚舉值1,枚舉值2,枚舉值3,枚舉值4,......      }

3)注意:每個枚舉值都可以看作是一個常量,所以枚舉值一般都用大寫字母表示 ;

              目前版本的 JDK,switch 語句支持 int,String,枚舉,但我們一般不這么使用枚舉;

4)栗子老師:(此程序寫的有些笨重,目的是為了更好的理解枚舉)

import java.util.Random;
public class pra{
    public static void main(String[] args) {
        Random random=new Random();
        int i=random.nextInt(101);
        Result result=power(i);
        if (result==Result.S){
            System.out.println("危險等級:S");
        }else if (result==Result.A){
            System.out.println("危險等級:A");
        }else if (result==Result.B){
            System.out.println("危險等級:B");
        }else if (result==Result.C){
            System.out.println("危險等級:C");
        }else System.out.println("危險等級:D");
    }
    public static Result power(int i){
        if (i>=95){
            return Result.S;
        }else if (i<95&&i>=85){
            return Result.A;
        }else if (i<85&&i>=70){
            return Result.B;
        }else if (i<70&&i>=50){
            return Result.C;
        }else return Result.D;
    }
}
enum Result{
    S,A,B,C,D
}

運行結果:
------------------------------
危險等級:D

Process finished with exit code 0

隨筆:

面試題:輸出幾?

 public class pra {
    public static void main(String[] args) {
        int Result=m();
        System.out.println(Result);
    }
    public static int m(){
        int i=100;
        try {
            return i;
        }finally {
            i++;
        }
    }
}
點擊查看結果
100

Process finished with exit code 0

結果是不是很意外?為什么不是 101 呢?這里接觸到了 java 中的語法規則(語法規則是 java 里優先級最高的,任何代碼都必須遵循規則)

原則一:方法里中的代碼必須遵循自上而下的順序依次執行;

原則二:return 語句一旦執行,整個方法必須結束;

所以綜合原則一與原則二,既然系統識別到了 return 語句就必須執行,但是結束方法之前,必須先執行 finally 中的“ i++ ”,雖然此時 i 的值確實等於 101 ,但是 return 要遵循原則一,不能輸出新 i ,只能輸出老 i = 100 ;

其實就像於:

int i=100;   
int j=i++;		//i 確實等於101
return j;       //但是系統被迫只能輸出 j !!!

由於博主目前只是一只猿寶寶,所以有些地方可能說的有些片面,若前輩們能夠指點一二就更好了      (~ ̄(OO) ̄)ブ

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM