JAVA--高級基礎開發

Day02【異常、線程】

  • 異常

1.1異常的概念:

  1. 異常: 指的是程序在執行過程當中,出現的非正常的狀況。最終會致使的JVM的正常中止。
  2. 異常自己就是一個類,產生異常就是建立異常對象並拋出了一個異常對象,java處理異常的方式,就是中斷處理。
  1. 異常:指的並非語法錯誤,編譯不經過,不能產生字節碼文件,程序根本沒法正常運行。
  2. 編寫一個良好的程序,應該避免異常發生從而終止整個程序,而是經過必定的技術來捕獲異常而且可以處理好,讓程序繼續運行。
  3. Java這門語言,自己就有處理異常的能力,咱們學習的就是怎麼掌握去處理異常的能力。
  4. Java異常的處理:實際上是5個關鍵字: try 、catch 、throw 、throws 、finally

1.2 異常的原理

  1. 拋出異常: 當程序運行期間,若是發生了異常,會自動的產生一個相應的異常類對象,而且會自動把這個異常類對象交給jvm,這個過程就是就是拋出異常。
  2. 捕獲並處理:jvm接收到異常類對象時,會自動的尋找有沒有相應的代碼可以處理該異常,若是存在可以處理該異常的代碼,則把異常讓其捕獲並處理,若是沒有找到相應的代碼,jvm會終止,程序退出。

1.3異常體系的分類

  1. 異常的處理機制就是幫助咱們找到程序中的問題,異常的根類是:java.lang.Throwable.

他底下有兩個子類:java.lang.Error與java.lang.Exception.咱們日常所說的異常,值的就是:java.lang.Exception.java

  1. Throwable 體系:
  1. Error: 嚴重的錯誤,沒法經過處理的錯誤,只能事先避免,好比絕症。例如:服務器宕機,jvm內部出錯。服務器資源耗盡。
  2. Exception: 表示異常,當異常出現後,程序猿或者攻城獅可以經過代碼方式去及時糾正,使程序繼續運行,是必需要處理的。
  3. 程序猿可以處理的只有Exception,對Error 無能爲力。
    1. Exception
    2. Exception根據異常的功能分爲:受檢異常和非受檢異常。
    3. 受檢異常:指的就是程序在編譯期間須要處理的異常。(javac 編譯期間異常)
    4. 非受檢異常: 程序在運行期間須要處理的異常。(java 運行期間的異常)
  • 數組下標越界。
  • 除數爲零。ArithmeticException
  • java.lang.RuntimeException 是全部非受檢異常的父類

1.5Throwable的經常使用方法

  1. public void printStackTrace():打印異常的詳細信息.
  • 包含了異常的緣由,異常的類型,還包括異常出現的位置。,在開發和調試階段都得使用 printStackTrace()方法。
  1. Public  String  getMessage();獲取異常發生的緣由。提示給用戶的時候,就提示異常發生的緣由。
  2. public String  toString():獲取異常的類型和異常描述信息(不常用)
  • 異常的處理
    1. 捕獲異常 try..catch
  1. 當異常出現的時候,程序會馬上終止,咱們的及時捕獲並處理異常。
  1. 在使用方法中咱們使用try…..catch 來捕獲處理異常。
  2. Try..catch 的方式就是來捕獲並處理異常,
  3. 捕獲異常:java 中對異常有針對性的語句進行捕獲,能夠對出現的異常進行指定方式的處理。【頗有針對性的去捕獲並處理】。

2法格式:數據庫

Try{數組

//編譯期間可能要出現異常的代碼服務器

}catch(異常類型  異常對象){網絡

   /打印異常的代碼jvm

  /打印異常的信息學習

}this

解析:try: 該代碼塊中編寫可能產生異常的代碼。spa

      Catch: 用來進行某種異常的捕獲,實現對異常捕獲的處理,線程

Try和catch 不能單獨使用,必須結合使用。

public class Test0 {

    public static void main(String[] args) {

        int  aa=10;

        int  bb=0;

        try{

            int  cc=aa/bb;

            System.out.println(cc);

         }catch (ArithmeticException ce){

            ce.printStackTrace();

        }

        System.out.println("執行了嗎??");

 

    }

}

 

經過以上程序咱們發現,catch 只能處理try中所對應的異常類型,若是發生的異常和catch不匹配。則是沒法處理的。所以try 後面能夠有多個catch出現,每一個catch處理不一樣的異常的類型。

public class Test0 {

    public static void main(String[] args) {

        int  aa=10;

        int  bb=0;

        int[]sum={1,2,3,4};

        try{

            int  cc=aa/bb;

            //數組下標越界://java.lang.ArrayIndexOutOfBoundsException

            System.out.println(sum[4]);

           System.out.println(cc);

         }catch (ArithmeticException ce){

            ce.printStackTrace();

        }catch (ArrayIndexOutOfBoundsException  ce){

            ce.printStackTrace();

        }

        System.out.println("執行了嗎??");

 

    }

}

 

 

  1. 若是try中有多個異常存在,則那個異常先發生,發生後就直接去找對應的catch,

Catch執行完後,代碼的順序是繼續從Catch往下執行的,不會返回try語句塊中,因此try..catch 會幫咱們捕獲異常,可是會影響程序的正常的流程,最終咱們仍是要程序猿手動去處理髮生的異常。

  1. 若是try下面有多個catch,catch中的異常類型若是是異常的父類,那麼他只能位於最後一個catch中。
    1. finally
  1. finally: 有一些特定的代碼,不管異常是否發生,都要去執行,另外,異常會引發程序的跳轉,致使有些代碼執行不到,而finally 就是解決這個問題,finally 語句塊中存放的代碼,必定會被執行到的。
  2. 那麼何時的代碼必須最終執行:
  • 當咱們在 try 語句塊中使用到了一些物理資源(磁盤文件、網絡鏈接、數據庫鏈接等對象時),咱們都得在使用完以後,最終關閉這些對象,來釋放它們所佔的內存資源。
  1. Finally的語法:
  1. Try….catch…..finally.
  2. Finally 也不能單獨使用。

 

      try{

            System.out.println(10/0);

        }catch (ArrayIndexOutOfBoundsException  ce){

            ce.printStackTrace();

        }finally {

            System.out.println("無論上面的異常是否執行,finall永遠執行!!");

        }

    }

    1. 拋出異常
  1. 在編寫程序時,咱們必需要考慮程序出現問題的狀況。好比,在定義方法時,方法須要接收參數,那麼,當調用方法時傳遞參數,那麼在方法中首選須要對參數進行合法的判斷,數據若不合法,就應該告訴調用者,傳遞合法的數據進來。這時須要使用拋出異常的方式來告訴調用者。
  2. 在 Java 中,提供了一個 throw 關鍵字,用來拋出一個指定的異常對象?那麼拋出異常對象後,咱們如何操作呢????
  1. 建立一個異常類對象,封住一些提示的信息。
  2. 須要將這個異常對象告知調用者,那麼怎麼才能告知調用者呢?怎麼將這個異常對象傳遞到調用者處。那麼咱們經過throw 關鍵字就能夠完成。
  3. 語法:throw  new 異常類(「要提示的信息」);
  4. Throw用在方法內,用來拋出一個異常類對象,這個異常對象傳遞到調用者處,並結束當前方法的執行。

例如:

1.throw new ArithmeticException(「除數不能爲零」);

2.throw new ArrayIndexOutOfBoundsException(「數組下標越界」);

5.

/throw 拋出異常

public class Test2 {

    public static void main(String[] args) {

        int[]num={1,2,3,4,5,6,7};

        int  index=10;

        getSting(num,index);

    }

public  static  void  getSting(int[]num,int index){

//判斷條件,若是知足,當執行完 throw 拋出異常對象後,方法已經沒法繼

續運行,這時就會結束當前方法的執行,並將其異常告知給調用者,這就是須要通

過異常來解決

 if(index<0||index>num.length){

            throw  new ArrayIndexOutOfBoundsException("主人數組的下標太大的");

//System.out.println("ha"); //位於 throw new 下面的代碼不會被執行,報錯

        }else{

            System.out.println(num[index]);

        }

    }

}

//運行的結果:Exception in thread "main"

// java.lang.ArrayIndexOutOfBoundsException: 主人數組的下標太大的

【注意】若是產生了異常,咱們就會將異常拋出,也就是將問題返回給該方法的調用者,那麼對於調用者來講,一種就是進行捕獲處理,另外一種就是繼續將異常拋出去,使用throw來聲明。

    1. 聲明異常throws
  1. 聲明異常: 就是將問題標識出來,報告給調用者,若是方法內經過throw 拋出了編譯時(受檢)異常,而沒有捕獲處理,那麼必須經過throws 來進行聲明,讓調用者本身去處理。
  2. 關鍵字throws 用於方法上來聲明一個異常,用於表示當前的方法不處理異常,而是提醒該方法的調用者來處理異常。
  3. 聲明異常的格式:

[訪問修飾符]  返回值類型  方法名(參數列表) throws  異常類名1….異常類2{

      //代碼塊

}

【注意】:throws只能用於方法的簽名的後面,而throw 只能用於方法體中。

    1. 異常實踐
  1. 儘可能減小try語句塊的體積,由於try中每句代碼的執行都須要判斷有沒有異常發生,影響了代碼執行的效率。
  2. 運行時異常被拋出能夠不處理,即不捕獲也不聲明,可是若是是受檢(編譯)異常被拋出,必須處理,一種throws來進行聲明,另外一種是利用 try….catch() 來進行捕獲並處理。
  3. 若是父類拋出 了多個異常,子類重寫父類的該方法時,只能拋出相同的異常或異常的子類。
  4. 父類方法沒有拋出異常,子類重寫父類的該方法時,也不能夠拋出異常,此時若是子類產生異常,只能聲明並處理,不能聲明拋出。
  5. 在開發和調式階段,建議吧異常的信息打印處理,方便解決問題。
      1.  

練習題:要求:

咱們模擬登陸操做,若是用戶名已存在,則拋出異常並提示:該用戶名已被註冊。

a)首選自定義一個登陸異常類 LoginException

b)模擬登陸操做,使用數組或者 ArrayList 模擬數據庫中存儲的數據,而且提供當前註冊帳號是否存在的方法用於判斷。

//自定義一個異常類

public class LoginException extends Exception{

    public LoginException() {

    }

 

    public LoginException(String message) {

        super(message);

    }

 

    public LoginException(String message, Throwable cause) {

        super(message, cause);

    }

 

    public LoginException(Throwable cause) {

        super(cause);

    }

 

    public LoginException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {

        super(message, cause, enableSuppression, writableStackTrace);

    }

}

 

public class Login {

    static String[]stuName={"liwenjie","zhangsan","李文傑","桑鳳嬌","郭朝旭"};

 

    public static void main(String[] args){

        Scanner input=new Scanner(System.in);

        System.out.println("請輸入用戶名");

        String  userName=input.next();

        try{

            boolean flag=display(userName);

            if(flag){

                System.out.println("用戶註冊成功");

            }

        }catch (Exception  ce){

            ce.printStackTrace();

        }

    }

    public static boolean display(String name)throws Exception{

        for(String  ss:stuName){

            if(ss.equals(name)){

                //拋出一個異常

                throw new LoginException("用戶名已被註冊過!!!");

            }

        }

        return true;

    }

}

 

 

//集合版的模擬登陸系統

public class Student{

    public static void main(String[] args) {

        Scanner  input=new Scanner(System.in);

        System.out.println("請輸入用戶名:");

        String username=input.next();

        try{

            boolean flag=meth(username);

            if(flag){

                System.out.println("註冊成功");

            }

        }catch (Exception  ce){

            ce.printStackTrace();

        }

    }

    public  static boolean meth(String  name)throws Exception{

        ArrayList<String>list=new ArrayList<>();

        list.add("sangfengjiao");

        list.add("liwnejie");

        list.add("mashitian");

        list.add("趙雲");

        list.add("zhangsan");

        for(String ss:list){

            if(ss.contains(name)){

                throw  new LoginException("用戶名已被註冊過!!!");

            }

        }

        return true;

    }

}

2.6 3. 自定義異常類

每個學生(Student)都有學號,姓名和分數,分數永遠不能爲負數。若是老師給學生賦值一個負數,拋出一個自定義異常。

 

//自定義異常類

public class Student2 {

    private  String  stuName;

    private Integer  stuXue;

    private Double   stuScore;

    public Student2(){

 

    }

    public Student2(String stuName,Integer stuXue,Double stuScore){

        this.stuName=stuName;

        this.stuXue=stuXue;

        this.stuScore=stuScore;

    }

 

    public String getStuName() {

        return stuName;

    }

 

    public void setStuName(String stuName) {

        this.stuName = stuName;

    }

 

    public Integer getStuXue() {

        return stuXue;

    }

 

    public void setStuXue(Integer stuXue) {

        this.stuXue = stuXue;

    }

 

    public Double getStuScore() {

        return stuScore;

    }

 

    public void setStuScore(Double stuScore){

        if(stuScore<0){

            throw new  StudentScore("分數不能爲負數!!!!");

        }else{

            this.stuScore = stuScore;

        }

 

    }

}

public class StudentScore  extends RuntimeException{

    public StudentScore() {

    }

 

    public StudentScore(String message) {

        super(message);

    }

 

    public StudentScore(String message, Throwable cause) {

        super(message, cause);

    }

 

    public StudentScore(Throwable cause) {

        super(cause);

    }

 

    public StudentScore(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {

        super(message, cause, enableSuppression, writableStackTrace);

    }

}

public class Stundent3 {

    public static void main(String[] args) {

        //建立Student對象

        Student2  ss=new Student2();

        ss.setStuName("李文傑");

        //拋出:day02.StudentScore: 分數不能爲負數!!!!

        ss.setStuScore(-100.0);

        ss.setStuXue(33);

        System.out.println(ss.getStuName());

        System.out.println(ss.getStuScore());

        System.out.println(ss.getStuXue());

    }

}

相關文章
相關標籤/搜索