從字面上講,就是不正常的現實就是異常。
程序中的異常也是要在程序運行中才會偶爾發生。如果程序還沒有運行,編譯就報錯,這種不叫異常,這種叫編譯錯誤,通常是語法上的錯誤
二、java中異常
Java 提供了兩類主要的異常:runtime exception 和checked exception。所有的checked exception 是從java.lang.Exception 類衍生出來的,而runtime exception 則是從java.lang.RuntimeException 或java.lang.Error類衍生出來的。它們的不同之處表現在兩方面:機制上和邏輯上
所有異常必須處理!在程序里可以拋異常,但是決不能把異常拋給最終用戶。BUG 在程序員手里還不是BUG,但是一旦交付,那么就是BUG
2.1、機制上runtime exceptions:
checked exceptions:
從邏輯的角度來說,checked exceptions 和runtime exception 是有不同的使用目的的。
checked exception 用來指示一種調用方能夠直接處理的異常情況。checked exception 迫使你捕獲它并處理這種異常情況。
而runtime exception 則用來指示一種調用方本身無法處理或恢復的程序錯誤。
三、程序中看異常3.1、例一package com.pb.demo6;import java.util.Scanner;/* * 求2個整數的商 * 當異常發生時,程序如何處理 */public class Test1 { public static void main(String[] args) { //從鍵盤獲得輸入 Scanner input=new Scanner(System.in); System.out.當輸入除數不是0時,正常運行,但當輸入的除數為0時,或者字符串時,就會報出異常:
請輸入被除數:2請輸入除數:0Exception in thread "main" java.lang.ArithmeticException: / by zero at com.pb.demo6.Test1.main(Test1.java:18)
請輸入被除數:ffdException in thread "main" java.util.InputMismatchException
同時也發現有異常發生時,最后的輸出語句并沒有執行
四、常見異常java.lang.ArithmeticExecption算術異常類。當出現異常的運算條件時,拋出此異常。比如程序中出現了“除以零”這樣的運算,就會出這樣的異常。對這種異常,大家就要好好檢查一下自己程序中,涉及到數學運算的地方,公式是不是有不妥了
java.lang.NullPointerException空指針異常類。簡單地說就是調用了未經初始化的對象或者是不存在的對象。當應用程序試圖在需要對象的地方使用null 時,拋出該異常這種情況包括:
- 調用null 對象的實例方法
- 訪問或修改null 對象的字段
- 將null 作為一個數組,獲得其長度
- 將null 作為一個數組,訪問或修改其時間片
- 將null 作為Throwable 值拋出
應用程序應該拋出該類的實例,指示其他對null 對象的非法使用
java.lang.ClassNotFoundException找不到類異常。當應用程序試圖使用以下方法通過字符串名加載類時,拋出該異常:
- Class 類中的forName 方法
- ClassLoader 類中的findSystemClass 方法
- ClassLoader 類中的loadClass 方法
java.lang.ArrayIndexOutOfBoundsException數組下標越界異常。用非法索引訪問數組時拋出的異常。如果索引為負或大于等于數組大小,則該索引為非法索引現在程序中大多都有對數組的操作,因此在調用數組的時候一定要認真檢查,看自己調用的下標是不是超出了數組的范圍,一般來說,顯示(即直接用常數當下標)調用不太容易出這樣的錯,但隱式(即用變量表示下標)調用就經常出錯了,還有一種情況,是程序中定義的數組的長度是通過某些特定方法決定的,不是事先聲明的,這個時候,最好先查看一下數組的length,以免出現這個異常
java.lang.IllegalArgumentException方法的參數錯誤異常。拋出的異常表明向方法傳遞了一個不合法或不正確的參數類庫中的方法在一些情況下都會引發這樣的錯誤,比如音量調節方法中的音量參數,如果寫成負數就會出現這個異常,再比如g.setColor(int red,intgreen,int blue)這個方法中的三個值,如果有超過255 的也會出現這個異常因此一旦發現這個異常,我們要做的,就是趕緊去檢查一下方法調用中的參數傳遞是不是出現了錯誤
java.lang.Illegalaccess
Exception沒有訪問權限異常。當應用程序試圖反射性地創建一個實例(而不是數組)、設置或獲取一個字段,或者調用一個方法,但當前正在執行的方法無法訪問指定類、字段、方法或構造方法的定義時,拋出該異常對程序中用了package 的情況下要注意這個異常java.lang.IncompatibleClassChangeError不兼容的類變化錯誤。當正在執行的方法所依賴的類定義,發生了不兼容的改變時,拋出該錯誤一般在修改了應用中的某些類的聲明定義,而沒有對整個應用重新編譯,而直接運行的情況下,容易引發該錯誤
java.lang.InstantiationError實例化錯誤。當應用程序試圖使用Java 的new 結構,來實例化一個抽象類或一個接口時,拋出該異常通常由編譯器捕獲此錯誤,如果類定義中存在不兼容的更改,則此錯誤將只可能發生在運行時
java.lang.LinkageError鏈接錯誤。該錯誤及其所有子類指示一個類在一定程度上依賴于另一個類;但是,在編譯前一個類之后,后一個類發生了不相容的改變
java.lang.StackOverflowError堆棧溢出錯誤。當一個應用遞歸調用的層次太深,而導致堆棧溢出時,拋出該錯誤
java.lang.NumberFormatException數字格式異常。當試圖將一個String 轉換為指定的數字類型,而該字符串卻不滿足數字類型要求的格式時,拋出該異常
java.lang.RuntimeException運行時異常。RuntimeException 是那些可能在Java 虛擬機正常運行期間拋出的異常的超類可能在執行方法期間拋出但未被捕獲的RuntimeException 的任何子類,都無需在throws 子句中進行聲明
java.io.IOException輸入輸出異常。當發生某種I/O 異常時,拋出此異常。此類是失敗或中斷的I/O 操作生成的異常的通用類
java.io.FileNotFoundException文件未找到異常。當試圖打開指定路徑名表示的文件失敗時,拋出此異常在不存在具有指定路徑名的文件時,此異常將由FileInputStream、FileOutputStream 和RandomAccessFile 構造方法拋出。如果該文件存在,但是由于某些原因不可訪問,比如試圖打開一個只讀文件進行寫入,則此時這些構造方法仍然會拋出該異常
java.io.EOFException文件已結束異常。當輸入過程中意外到達文件或流的末尾時,拋出此異常此異常主要被數據輸入流用來表明到達流的末尾。注意,其他許多輸入操作返回一個特殊值表示到達流的末尾,而不是拋出異常
java.lang.InterruptedException被中止異常。當線程在活動之前,或活動期間處于正在等待、休眠或占用狀態,且該線程被中斷時,拋出該異常有時候,一種方法可能希望,測試當前線程是否已被中斷,如果已被中斷,則立即拋出此異常
五、異常處理5.1、語法格式:try{ // 有可能出現異常的語句}catch(異常類 異常對象){ // 編寫異常的處理語句}[ catch(異常類 異常對象){ // 編寫異常的處理語句} catch(異常類 異常對象){ // 編寫異常的處理語句} …. ][finally{ 一定會運行到的程序代碼 ; }
主要搭配:try-catch、try-catch-finally、try-finally三種形式
5.2、多個異常如果同時有多個catch塊,Exception 必須放在最后一個catch塊中
package com.pb.demo6;import java.util.InputMismatchException;import java.util.Scanner;import javax.naming.AuthenticationException;/* * 求2個整數的商 * 當異常發生時,程序如何處理 */public class Test1 { public static void main(String[] args) { //從鍵盤獲得輸入 try{ Scanner input=new Scanner(System.in); System.out.println("請輸入被除數:"); int num1=input.nextInt(); System.out.println("請輸入除數:"); int num2=input.nextInt(); int result=num1/num2; System.out.println(num1+"與"+num2+"的商: "+result); }catch(InputMismatchException e){ System.out.println("輸入的不是數字"); e.printStackTrace(); }catch(ArithmeticException e){ System.out.println("除數不能為0"); e.printStackTrace(); }catch(Exception e){ System.out.println("其它錯誤!"); e.printStackTrace(); }finally{ System.out.println("謝謝使用!"); } }}請輸入被除數:2請輸入除數:0除數不能為0java.lang.ArithmeticException: / by zero at com.pb.demo6.Test1.main(Test1.java:22)謝謝使用!
在finally中的語句,不管出不出異常都會被執行.
但如果在catch塊中:執行System.exit(0);或者System.exit(-1);程序將直接結束,finally中的語句將不會執行
5.3、Java的異常處理機制在整個java的異常處理中,實際上也是按照面向對象的方式進行處理,處理的步驟如下:
package com.pb.demo6;import java.util.InputMismatchException;import java.util.Scanner;import javax.naming.AuthenticationException;/* * 求2個整數的商 * 當異常發生時,程序如何處理 */public class Test2 { public static void main(String[] args) { try { divide(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //除法運算 public static void divide () throws Exception{ //從鍵盤獲得輸入 Scanner input=new Scanner(System.in); System.out.println("請輸入被除數:"); int num1=input.nextInt(); System.out.println("請輸入除數:"); int num2=input.nextInt(); int result=num1/num2; System.out.println(num1+"與"+num2+"的商: "+result); }}6.2、throw關鍵字與throws不同的是,可以直接使用throw拋出一個異常。拋出的時候直接拋出異常類的實例化對象即可package com.pb.demo6;/* * 人類 */public class Person { private String name; private String sex; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) throws Exception { if(sex.equals("男") || sex.equals("女")){ this.sex = sex; }else{ throw new Exception("性別只能是男或者女"); } } public int getAge() { return age; } public void setAge(int age) { if(age>=0 && age<=150){ this.age = age; }else{ try { throw new Exception("年齡只能在0-150歲之間!"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void printSelf(){ System.out.println("姓名:"+this.name+" 性別:"+this.sex+" 年齡:"+this.age); }}package com.pb.demo6;public class PersonTest { public static void main(String[] args) { Person p=new Person(); try { p.setName("張三"); p.setSex("不男不女"); p.setAge(200); p.printSelf(); } catch (Exception e) { e.getMessage(); e.printStackTrace(); } }}七、自定義異常在Java中已經提供了大量的異常類,但是這些異常類有些時候也很難滿足開發者的要求,所以此時用戶可以根據自己的需要定義自己的異常類,定義異常類,只需要繼承Exception類即可。當然可以繼承其它的如:Exception,Throwable,RuntimeException及其子類,其中繼承Exception,Throwable,效果,如果不要求調用者一定要處理拋出的異常可以繼承RuntimeException及其子類調用時只需要throw new 自定義異常名(信息)package com.pb.demo6;public class MyException extends Exception { public MyException() { super(); // TODO Auto-generated constructor stub } public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); // TODO Auto-generated constructor stub } public MyException(String message, Throwable cause) { super(message, cause); // TODO Auto-generated constructor stub } public MyException(String message) { super(message); // TODO Auto-generated constructor stub } public MyException(Throwable cause) { super(cause); // TODO Auto-generated constructor stub } }package com.pb.demo6;/* * 人類 */public class Person { private String name; private String sex; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) throws Exception { if(sex.equals("男") || sex.equals("女")){ this.sex = sex; }else{ throw new MyException("性別只能是男或者女"); } } public int getAge() { return age; } public void setAge(int age) { if(age>=0 && age<=150){ this.age = age; }else{ try { throw new MyException("年齡只能在0-150歲之間!"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void printSelf(){ System.out.println("姓名:"+this.name+" 性別:"+this.sex+" 年齡:"+this.age); }}package com.pb.demo6;public class PersonTest { public static void main(String[] args) { Person p=new Person(); try { p.setName("張三"); p.setSex("不男不女"); p.setAge(200); p.printSelf(); } catch (Exception e) { e.getMessage(); e.printStackTrace(); } }}com.pb.demo6.MyException: 性別只能是男或者女
這時獲得的異常就是我們自定義的異常新聞熱點
疑難解答