Java的異常處理辦法 try catch throws
異常處理常見手段: try catch finally throws
步驟 1 : try catch
1.將可能拋出FileNotFoundException 文件不存在異常的代碼放在try裏
2.如果文件存在,就會順序往下執行,並且不執行catch塊中的代碼
3. 如果文件不存在,try 裏的代碼會立即終止,程序流程會運行到對應的catch塊中
4. e.printStackTrace(); 會打印出方法的調用痕跡,如此例,會打印出異常開始於TestException的第16行,這樣就便於定位和分析到底哪裏出了異常
package exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class TestException {
public static void main(String[] args) {
File f= new File("d:/LOL.exe");
try{
System.out.println("試圖打開 d:/LOL.exe");
new FileInputStream(f);
System.out.println("成功打開");
}
catch(FileNotFoundException e){
System.out.println("d:/LOL.exe不存在");
e.printStackTrace();
}
}
}
步驟 2 : 使用異常的父類進行catch
FileNotFoundException是Exception的子類,使用Exception也可以catch住FileNotFoundException
package exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class TestException {
public static void main(String[] args) {
File f= new File("d:/LOL.exe");
try{
System.out.println("試圖打開 d:/LOL.exe");
new FileInputStream(f);
System.out.println("成功打開");
}
catch(Exception e){
System.out.println("d:/LOL.exe不存在");
e.printStackTrace();
}
}
}
步驟 3 : 多異常捕捉辦法1
有的時候一段代碼會拋出多種異常,比如
new FileInputStream(f);
Date d = sdf.parse("2016-06-03");
這段代碼,會拋出 文件不存在異常 FileNotFoundException 和 解析異常ParseException
解決辦法之一是分別進行catch
package exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestException {
public static void main(String[] args) {
File f = new File("d:/LOL.exe");
try {
System.out.println("試圖打開 d:/LOL.exe");
new FileInputStream(f);
System.out.println("成功打開");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse("2016-06-03");
} catch (FileNotFoundException e) {
System.out.println("d:/LOL.exe不存在");
e.printStackTrace();
} catch (ParseException e) {
System.out.println("日期格式解析錯誤");
e.printStackTrace();
}
}
}
步驟 4 : 多異常捕捉辦法2
另一個種辦法是把多個異常,放在一個catch裏統一捕捉
catch (FileNotFoundException | ParseException e) {
這種方式從 JDK7開始支持,好處是捕捉的代碼更緊湊,不足之處是,一旦發生異常,不能確定到底是哪種異常,需要通過instanceof 判斷具體的異常類型
package exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestException {
public static void main(String[] args) {
File f = new File("d:/LOL.exe");
try {
System.out.println("試圖打開 d:/LOL.exe");
new FileInputStream(f);
System.out.println("成功打開");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse("2016-06-03");
} catch (FileNotFoundException | ParseException e) {
if (e instanceof FileNotFoundException)
System.out.println("d:/LOL.exe不存在");
if (e instanceof ParseException)
System.out.println("日期格式解析錯誤");
e.printStackTrace();
}
}
}
步驟 5 : finally
無論是否出現異常,finally中的代碼都會被執行
package exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class TestException {
public static void main(String[] args) {
File f= new File("d:/LOL.exe");
try{
System.out.println("試圖打開 d:/LOL.exe");
new FileInputStream(f);
System.out.println("成功打開");
}
catch(FileNotFoundException e){
System.out.println("d:/LOL.exe不存在");
e.printStackTrace();
}
finally{
System.out.println("無論文件是否存在, 都會執行的代碼");
}
}
}
步驟 6 : throws
考慮如下情況:
主方法調用method1
method1調用method2
method2中打開文件
method2中需要進行異常處理
但是method2不打算處理,而是把這個異常通過throws拋出去
那麼method1就會接到該異常。 處理辦法也是兩種,要麼是try catch處理掉,要麼也是拋出去。
method1選擇本地try catch住 一旦try catch住了,就相當於把這個異常消化掉了,主方法在調用method1的時候,就不需要進行異常處理了
package exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class TestException {
public static void main(String[] args) {
method1();
}
private static void method1() {
try {
method2();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void method2() throws FileNotFoundException {
File f = new File("d:/LOL.exe");
System.out.println("試圖打開 d:/LOL.exe");
new FileInputStream(f);
System.out.println("成功打開");
}
}
步驟 7 : throw和throws的區別
throws與throw這兩個關鍵字接近,不過意義不一樣,有如下區別:
- throws 出現在方法聲明上,而throw通常都出現在方法體內。
- throws 表示出現異常的一種可能性,並不一定會發生這些異常;throw則是拋出了異常,執行throw則一定拋出了某個異常對象。
練習: 異常處理
假設有一個方法 public int method(), 會返回一個整數
在這個方法中有try catch 和 finally.
try 裏返回 1
catch 裏 返回 2
finally 裏 返回3
那麼,這個方法到底返回多少?
答案:
package exception;
public class TestException {
public static int method() {
try {
return return1();
} catch (Exception e) {
return return2();
} finally {
return return3();
}
}
private static int return1() {
System.out.println("return 1");
return 1;
}
private static int return2() {
System.out.println("return 2");
return 2;
}
private static int return3() {
System.out.println("return 3");
return 3;
}
public static void main(String[] args) {
int result = method();
System.out.println("result:" + result);
}
}
可以看到,最後結果是取finally的返回值3.
同時,故意把method設計成調用 return1(),return2(),return3()。
可以觀察到,try裏的 返回和 finally的返回都是執行了的,不過最後選擇使用finally裏的返回的值