異常:
1.概述:
程序出現的不正常的情況。
2.異常的體系:
Throwable
|--Error 這種問題是一個嚴重問題,一般出現這種問題,需要一起解決(程序員只能避免嚴重問題),比如:內存溢出(OutOfMemory);|--Exception
|--RuntimeException 運行期異常,我們需要修正代碼|--非RuntimeException 編譯期異常,必須處理的,否則程序編譯不通過
3.異常的描述:
哪一個包下的異常,並且將報錯信息打印在控制檯。
4.異常的處理:
a.JVM的默認處理
把異常的名稱,原因,位置等信息輸出在控制檯。
b.自己處理
i.捕獲異常 try...catch..finallyii.拋出異常 thorws
捕獲異常:
1.格式:
try{
可能出現問題的代碼;
}catch(異常類名 變量名){
輸出語句;
}finally{
釋放資源;
}
如果try裏面的代碼出現問題了,jvm會生成異常對象,然後拋出來和catch中描述的這個異常信息進行匹配,判斷如果一致,這裏會輸出處理語句(輸出語句)//可能出現問題的代碼如果和catch裏面的異常類名能匹配,則打印輸出語句。
2.變形方式:
try{
可能出現問題的代碼
}catch(異常類名 變量名){
提示信息
}
try...catch...try...catch...catchtry...catch...catch...finally(開發常用)
3.兩個異常的處理:
a.一個一個去try...catchb.一個try,多個catch注意:
a.在實際開發中,捕獲異常的時候,最好給出具體的異常類,不要隨意使用Exceptionb.捕獲異常:使用一個try多個catch的情況,catch中異常類名是一種平級關係,如果出現父子關係,那麼這種將最大的異常寫在最後。
4.JDK7以後出現的新的捕獲異常的方式
try{
可能出現問題的代碼
}catch(異常類名1 變量名1){
提示
}catch(異常類名2 變量名2){
......
}
新的方式:try{
可能出現問題的代碼
}catch(異常類名1 | 異常類名2 | 異常類名3 變量名){
......
}注意:
有一個弊端,不夠好,在開發中,可能出現同類型問題,需要捕獲同一個異常信息。
5.java程序中編譯時期異常和運行時期異常的區別:
a.編譯時期異常:需要我們去處理,否則編譯不通過,顯示處理b.運行時期異常:無序顯示處理,也可以像編譯時期異常處理一樣
6.異常類中的一些方法:
public String getMessage():返回的是一個異常的消息字符串piblic String toString():返回的是一個簡單的描述信息當前類對象 name:全路徑名":"(冒號:空格) + getMessage()public void printStackTrace():描述異常信息,以及出現的具體位置在哪裏,返回的是void類型,直接在控制檯的!
public class Demo1 { public static void main(String[] args) { Method1(); Method2(); } private static void Method2() { int []a={1,2,3}; try { System.out.println(a[3]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("數組越界了"); } } private static void Method1() { int a = 10; int b = 0; try { System.out.println(a/b); } catch (ArithmeticException e) { System.out.println("分母不能爲0"); } } }
public class Demo2 { public static void main(String[] args) { int a = 10 ; int b = 0; int []c={1,2,3}; try { System.out.println(a/b); System.out.println(c[3]); } catch (ArithmeticException e ){ System.out.println("分母不能爲0"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("數組越界了"); } } }
拋出異常(thorws):
1.爲什麼要使用拋出異常:
當我們處理異常,如果沒有一些權限處理異常,那我們就不處理了,通過開發工具,提示拋出異常。
2.throws和throw的區別?
a.thorws:
一般是在方法聲明上拋出。拋出的是一個異常類名,可以拋出多個異常,中間用逗號隔開。throws表示拋出異常,這段代碼可能會拋出異常( 指的是拋出異常的可能性).一般情況,throws用的比較多
b.thorw:
一般在方法中進行拋出拋出的是一個異常類對象(匿名對象的方式)throw表示拋出,肯定的拋出異常(具體異常),走到這塊代碼,一定會執行throw中的異常 在語句中進行處理
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class Demo02 { public static void main(String[] args) throws ParseException { //定義字符串變量 String s = "2017-8-8"; //創建對象 SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d = sd.parse(s);//編譯時期異常需要拋出異常 System.out.println(d); } } /* out: Exception in thread "main" java.text.ParseException: Unparseable date: "2017-8-8" at java.text.DateFormat.parse(DateFormat.java:366) at Exception.Demo02.main(Demo02.java:13) */
public class Demo01 { public static void main(String[] args) throws Exception { fun1(); fun2(); } private static void fun1() throws Exception{ //定義兩個變量 int a = 1; int b = 0; if(b==0){ throw new ArithmeticException();//代碼走到這塊:表示一定會執行這個異常 }else{ System.out.println(a/b); } } private static void fun2() throws Exception { //可能會拋出異常 //定義兩個變量 int a = 1; int b = 0; if(b==0){ throw new Exception();//直接指定的異常:大方向的異常 }else{ System.out.println(a/b); } } }
finally關鍵字和異常類相關問題
1.概述:
finally用於釋放資源,它的代碼永遠會執行。特殊情況:在執行到finally之前jvm退出了注意:finally中的代碼是一定會執行的,一般用在IO流中和數據庫中;
2.執行代碼的順序:
try{
可能出現問題的代碼;
}catch(異常類名 變量名){
輸出語句;
}finally{
釋放資源;
}
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class finallyDemo { public static void main(String[] args) { //定義字符串 String s = "2017-8-9"; //創建對象 SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 定義一個變量 Date d = null; try { d=sd.parse(s); } catch (ParseException e) { e.printStackTrace(); // System.exit(0);//jvm退出 } finally{ System.out.println("這裏必須執行,用來釋放資源"); } System.out.println("d:"+d); } } /* out: java.text.ParseException: Unparseable date: "2017-8-9" at java.text.DateFormat.parse(DateFormat.java:366) at Exception.finallyDemo.main(finallyDemo.java:27) 這裏必須執行,用來釋放資源 d:null
3.final、finalize、finally三者之間的區別?(★★★★★)
a.final:最終的,終態的
final修飾類,該類不能被繼承final修飾成員變量,該變量是自定義常量final修飾成員方法,該方法不能被重寫
b.finalize
和垃圾回收期有關係:運行垃圾回收器的方法:gc().調用gc(),實質是調用了通過重寫了Object中的finalize方法
c.finally
出現在IO流中或者數據中,用來釋放資源的!
4.(面試題)如果catch有return語句,finally中的會執行嗎?如果會,是在return前執行還是在return後執行?
會執行finally中的代碼,是在return前執行確切的說實在代碼中間執行!
public class finallyDemo2_return { public static void main(String[] args) { System.out.println(fun());//30 } public static int fun() { int a = 10 ; try{ a = 20; System.out.println(a/0); }catch(Exception e){ a = 30; return a; /* * 此時 * a = 30;return 30 * 但是有finally 所以會執行finally裏的代碼 */ }finally{ a = 40; // return a; } return a; } }
5.異常類的注意事項:
a.父的方法有異常拋出,子的重寫方法在拋出異常的時候必須要小於(異常類的子類)等於父的異常b.父的方法沒有異常拋出,子的重寫方法不能有異常拋出只能 try...catch(這種情況只能子類中進行捕獲異常);c.父的方法拋出多個異常,子的重寫方法必須比父少或者小
6.自定義異常:
有時候在實際開發中,可能會需要自己定義一個異常類;不是說起以類名就是可以當作異常類,必須自定義的類繼承Exception或者RuntimeException,那麼這樣的類,纔是自己定義的異常類
public class MyException extends Exception {
//添加空參數構造
public MyException(){}
public MyException(String m){
super(m);
}
}
import java.util.Scanner;
public class StudentDemo {
public static void main(String[] args) {
//創建鍵盤錄入對象
Scanner sc = new Scanner(System.in) ;
//錄入並接收數據
System.out.println("請輸入您的成績:");
int score = sc.nextInt() ;
//創建老師對象
Teacher t = new Teacher() ;
try {
t.check(score);
} catch (MyException e) {
e.printStackTrace();
}
}
}
public class Teacher {
//檢查分數的方法
public static void check(int score) throws MyException{
//成績大於100或者成績小於0
if(score>100 || score<0){
System.out.println("成績必須在0~100之間");
}else{
System.out.println("符合我們的成績規則...");
}
}
}