1.運行時異常 是指編譯器不要求強制處置的異常。通常是指編程時的邏輯錯誤,是程序 員應該積極避免其出現的異常。java.lang.RuntimeException類及它的子 類都是運行時異常。 對於這類異常,能夠不做處理,由於這類異常很廣泛,若全處理可能會對 程序的可讀性和運行效率產生影響。 2.編譯時異常 是指編譯器要求必須處置的異常。即程序在運行時因爲外界因素形成的一 般性異常。編譯器要求Java程序必須捕獲或聲明全部編譯時異常。 對於這類異常,若是程序不處理,可能會帶來意想不到的結果。
常見異常
java.lang.RuntimeException
ClassCastException
ArrayIndexOutOfBoundsException
NullPointerException
ArithmeticException
NumberFormatException
InputMismatchException
。。。
java.io.IOExeption
FileNotFoundException
EOFException
java.lang.ClassNotFoundException
java.lang.InterruptedException
java.io.FileNotFoundException
java.sql.SQLException
package com.atguigu.java; /* * Error: * Java虛擬機沒法解決的嚴重問題。如:JVM系統內部錯誤、資源耗盡等嚴重狀況。好比:StackOverflowError和OOM。 * * 通常不編寫針對性的代碼進行處理。 * * */ public class ErrorTest { public static void main(String[] args) { //1.棧溢出:java.lang.StackOverflowError // main(args); //2.堆溢出:java.lang.OutOfMemoryError Integer[] arr = new Integer[1024*1024*1024]; } }
package com.atguigu.java1; import java.io.File; import java.io.FileInputStream; import java.util.Date; import java.util.Scanner; import org.junit.Test; /* * 1、異常體系結構 * * java.lang.Throwable * |-----java.lang.Error:通常不編寫針對性的代碼進行處理。 * |-----java.lang.Exception:能夠進行異常的處理 * |------編譯時異常(checked) * |-----IOException * |-----FileNotFoundException * |-----ClassNotFoundException * |------運行時異常(unchecked,RuntimeException) * |-----NullPointerException * |-----ArrayIndexOutOfBoundsException * |-----ClassCastException * |-----NumberFormatException * |-----InputMismatchException * |-----ArithmeticException * * * * 面試題:常見的異常都有哪些?舉例說明 */ public class ExceptionTest { //******************如下是編譯時異常*************************** @Test public void test7(){ // File file = new File("hello.txt"); // FileInputStream fis = new FileInputStream(file); // // int data = fis.read(); // while(data != -1){ // System.out.print((char)data); // data = fis.read(); // } // // fis.close(); } //******************如下是運行時異常*************************** //ArithmeticException @Test public void test6(){ int a = 10; int b = 0; System.out.println(a / b); } //InputMismatchException @Test public void test5(){ Scanner scanner = new Scanner(System.in); int score = scanner.nextInt(); System.out.println(score); scanner.close(); } //NumberFormatException @Test public void test4(){ String str = "123"; str = "abc"; int num = Integer.parseInt(str); } //ClassCastException @Test public void test3(){ Object obj = new Date(); String str = (String)obj; } //IndexOutOfBoundsException @Test public void test2(){ //ArrayIndexOutOfBoundsException // int[] arr = new int[10]; // System.out.println(arr[10]); //StringIndexOutOfBoundsException String str = "abc"; System.out.println(str.charAt(3)); } //NullPointerException @Test public void test1(){ // int[] arr = null; // System.out.println(arr[3]); String str = "abc"; str = null; System.out.println(str.charAt(0)); } }
package com.atguigu.java1; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.junit.Test; /* * 1、異常的處理:抓拋模型 * * 過程一:"拋":程序在正常執行的過程當中,一旦出現異常,就會在異常代碼處生成一個對應異常類的對象。 * 並將此對象拋出。 * 一旦拋出對象之後,其後的代碼就再也不執行。 * * 關於異常對象的產生:① 系統自動生成的異常對象 * ② 手動的生成一個異常對象,並拋出(throw) * * 過程二:"抓":能夠理解爲異常的處理方式:① try-catch-finally ② throws * * * 2、try-catch-finally的使用 * * try{ * //可能出現異常的代碼 * * }catch(異常類型1 變量名1){ * //處理異常的方式1 * }catch(異常類型2 變量名2){ * //處理異常的方式2 * }catch(異常類型3 變量名3){ * //處理異常的方式3 * } * .... * finally{ * //必定會執行的代碼 * } * * 說明: * 1. finally是可選的。 * 2. 使用try將可能出現異常代碼包裝起來,在執行過程當中,一旦出現異常,就會生成一個對應異常類的對象,根據此對象 * 的類型,去catch中進行匹配 * 3. 一旦try中的異常對象匹配到某一個catch時,就進入catch中進行異常的處理。一旦處理完成,就跳出當前的 * try-catch結構(在沒有寫finally的狀況)。繼續執行其後的代碼 * 4. catch中的異常類型若是沒有子父類關係,則誰聲明在上,誰聲明在下無所謂。 * catch中的異常類型若是知足子父類關係,則要求子類必定聲明在父類的上面。不然,報錯 * 5. 經常使用的異常對象處理的方式: ① String getMessage() ② printStackTrace() * 6. 在try結構中聲明的變量,再出了try結構之後,就不能再被調用 * 7. try-catch-finally結構能夠嵌套 * * 體會1:使用try-catch-finally處理編譯時異常,是得程序在編譯時就再也不報錯,可是運行時仍可能報錯。 * 至關於咱們使用try-catch-finally將一個編譯時可能出現的異常,延遲到運行時出現。 * * 體會2:開發中,因爲運行時異常比較常見,因此咱們一般就不針對運行時異常編寫try-catch-finally了。 * 針對於編譯時異常,咱們說必定要考慮異常的處理。 */ public class ExceptionTest1 { @Test public void test2(){ try{ File file = new File("hello.txt"); FileInputStream fis = new FileInputStream(file); int data = fis.read(); while(data != -1){ System.out.print((char)data); data = fis.read(); } fis.close(); }catch(FileNotFoundException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } } @Test public void test1(){ String str = "123"; str = "abc"; int num = 0; try{ num = Integer.parseInt(str); System.out.println("hello-----1"); }catch(NumberFormatException e){ // System.out.println("出現數值轉換異常了,不要着急...."); //String getMessage(): // System.out.println(e.getMessage()); //printStackTrace(): e.printStackTrace(); }catch(NullPointerException e){ System.out.println("出現空指針異常了,不要着急...."); }catch(Exception e){ System.out.println("出現異常了,不要着急...."); } System.out.println(num); System.out.println("hello-----2"); } }
package com.atguigu.java1; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.junit.Test; /* * try-catch-finally中finally的使用: * * * 1.finally是可選的 * * 2.finally中聲明的是必定會被執行的代碼。即便catch中又出現異常了,try中有return語句,catch中有 * return語句等狀況。 * * 3.像數據庫鏈接、輸入輸出流、網絡編程Socket等資源,JVM是不能自動的回收的,咱們須要本身手動的進行資源的 * 釋放。此時的資源釋放,就須要聲明在finally中。 * * * */ public class FinallyTest { @Test public void test2(){ FileInputStream fis = null; try { File file = new File("hello1.txt"); fis = new FileInputStream(file); int data = fis.read(); while(data != -1){ System.out.print((char)data); data = fis.read(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(fis != null) fis.close(); } catch (IOException e) { e.printStackTrace(); } } } @Test public void testMethod(){ int num = method(); System.out.println(num); } public int method(){ try{ int[] arr = new int[10]; System.out.println(arr[10]); return 1; }catch(ArrayIndexOutOfBoundsException e){ e.printStackTrace(); return 2; }finally{ System.out.println("我必定會被執行"); return 3; } } @Test public void test1(){ try{ int a = 10; int b = 0; System.out.println(a / b); }catch(ArithmeticException e){ e.printStackTrace(); // int[] arr = new int[10]; // System.out.println(arr[10]); }catch(Exception e){ e.printStackTrace(); } // System.out.println("我好帥啊!!!~~"); finally{ System.out.println("我好帥啊~~"); } } }
package com.atguigu.java1; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /* * 異常處理的方式二:throws + 異常類型 * * 1. "throws + 異常類型"寫在方法的聲明處。指明此方法執行時,可能會拋出的異常類型。 * 一旦當方法體執行時,出現異常,仍會在異常代碼處生成一個異常類的對象,此對象知足throws後異常 * 類型時,就會被拋出。異常代碼後續的代碼,就再也不執行! * * 2. 體會:try-catch-finally:真正的將異常給處理掉了。 * throws的方式只是將異常拋給了方法的調用者。 並無真正將異常處理掉。 * * 3. 開發中如何選擇使用try-catch-finally 仍是使用throws? * 3.1 若是父類中被重寫的方法沒有throws方式處理異常,則子類重寫的方法也不能使用throws,意味着若是 * 子類重寫的方法中有異常,必須使用try-catch-finally方式處理。 * 3.2 執行的方法a中,前後又調用了另外的幾個方法,這幾個方法是遞進關係執行的。咱們建議這幾個方法使用throws * 的方式進行處理。而執行的方法a能夠考慮使用try-catch-finally方式進行處理。 * */ public class ExceptionTest2 { public static void main(String[] args){ try{ method2(); }catch(IOException e){ e.printStackTrace(); } // method3(); } public static void method3(){ try { method2(); } catch (IOException e) { e.printStackTrace(); } } public static void method2() throws IOException{ method1(); } public static void method1() throws FileNotFoundException,IOException{ File file = new File("hello1.txt"); FileInputStream fis = new FileInputStream(file); int data = fis.read(); while(data != -1){ System.out.print((char)data); data = fis.read(); } fis.close(); System.out.println("hahaha!"); } }
package com.atguigu.java2; public class StudentTest { public static void main(String[] args) { try { Student s = new Student(); s.regist(-1001); System.out.println(s); } catch (Exception e) { // e.printStackTrace(); System.out.println(e.getMessage()); } } } class Student{ private int id; public void regist(int id) throws Exception { if(id > 0){ this.id = id; }else{ // System.out.println("您輸入的數據非法!"); //手動拋出異常對象 // throw new RuntimeException("您輸入的數據非法!"); // throw new Exception("您輸入的數據非法!"); throw new MyException("不能輸入負數"); //錯誤的 // throw new String("不能輸入負數"); } } @Override public String toString() { return "Student [id=" + id + "]"; } }
package com.atguigu.java2; /* * 如何自定義異常類? * 1. 繼承於現有的異常結構:RuntimeException 、Exception * 2. 提供全局常量:serialVersionUID * 3. 提供重載的構造器 * */ public class MyException extends Exception{ static final long serialVersionUID = -7034897193246939L; public MyException(){ } public MyException(String msg){ super(msg); } }
package com.atguigu.java2; public class ReturnExceptionDemo { static void methodA() { try { System.out.println("進入方法A"); throw new RuntimeException("製造異常"); } finally { System.out.println("用A方法的finally"); } } static void methodB() { try { System.out.println("進入方法B"); return; } finally { System.out.println("調用B方法的finally"); } } public static void main(String[] args) { try { methodA(); } catch (Exception e) { System.out.println(e.getMessage()); } methodB(); } }
/*
進入方法A
用A方法的finally
製造異常
進入方法B
調用B方法的finallyjava
*/面試
package com.atguigu.exer; /* * 編寫應用程序EcmDef.java,接收命令行的兩個參數,要求不能輸入負數,計算兩數相除。 對數據類型不一致(NumberFormatException)、缺乏命令行參數(ArrayIndexOutOfBoundsException、 除0(ArithmeticException)及輸入負數(EcDef 自定義的異常)進行異常處理。 提示: (1)在主類(EcmDef)中定義異常方法(ecm)完成兩數相除功能。 (2)在main()方法中使用異常處理語句進行異常處理。 (3)在程序中,自定義對應輸入負數的異常類(EcDef)。 (4)運行時接受參數 java EcmDef 20 10 //args[0]=「20」 args[1]=「10」 (5)Interger類的static方法parseInt(String s)將s轉換成對應的int值。 如:int a=Interger.parseInt(「314」); //a=314; */ public class EcmDef { public static void main(String[] args) { try{ int i = Integer.parseInt(args[0]); int j = Integer.parseInt(args[1]); int result = ecm(i,j); System.out.println(result); }catch(NumberFormatException e){ System.out.println("數據類型不一致"); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("缺乏命令行參數"); }catch(ArithmeticException e){ System.out.println("除0"); }catch(EcDef e){ System.out.println(e.getMessage()); } } public static int ecm(int i,int j) throws EcDef{ if(i < 0 || j < 0){ throw new EcDef("分子或分母爲負數了!"); } return i / j; } }
package com.atguigu.exer; //自定義異常類 public class EcDef extends Exception { static final long serialVersionUID = -33875164229948L; public EcDef() { } public EcDef(String msg) { super(msg); } }