文章目錄
問題1:try/catch/finally執行順序問題
1.代碼
- 問下述代碼能否編譯通過?如果能,輸出是?
public class Demo03 {
public static void main(String[] args) {
try {
String s = null;
return;
}catch (Exception e){
System.out.println("catch");
}finally {
System.out.println("finally");
}
}
}
2.分析
-
上述代碼可以編譯通過,輸出
finally
-
這其實很簡單,進入try代碼塊,執行
return
前的內容,然後沒有發生異常則進入到finally
代碼塊中的內容,然後再執行return
3.問題1.1
- 下述代碼能否編譯通過?輸出是?
public class Demo03 {
public static void main(String[] args) {
try {
String s = null;
System.exit(0);
// return;
}catch (Exception e){
System.out.println("catch");
}finally {
System.out.println("finally");
}
}
}
-
可以編譯通過,什麼都不輸出
-
注意到代碼
System.exit(0);
,遇到它的時候就不會再去執行finally
中的代碼,而是直接退出程序,這表示結束正在運行中的虛擬機 -
一般來說
finally
中的代碼是一定會被執行的,但是這是唯一的特殊情況,因爲虛擬機都沒了,後面的代碼肯定都沒辦法執行
問題2:兩類異常的不同處理方式
運行期異常,編譯期異常
1.問題引入
- 下述代碼能否編譯通過
public class ExceptionTest {
public void doSomething() throws ArithmeticException{
System.out.println("do");
}
public static void main(String[] args) {
ExceptionTest test = new ExceptionTest();
test.doSomething();
}
}
-
可以通過,
ArithmeticException
是一個運行期異常,可以對其不做處理,最後會被拋出到虛擬機中處理 -
下述代碼能否編譯通過?
public class ExceptionTest {
public void doSomething() throws IOException {
System.out.println("do");
}
public static void main(String[] args) {
ExceptionTest test = new ExceptionTest();
test.doSomething();
}
}
-
不能,
IOException
是一個編譯期異常, 必須顯式的向上拋出
-
修改上述代碼,可以編譯通過
2小結
上述問題的本質是對於兩種不同異常處理方式
checked exception
:編譯期異常,都是java.lang.Exception
的子類,必須進行處理,有兩種處理方式- 繼續向上拋出,消極的做法,直到跑到JVM
- 主動的用
try...catch
進行處理
unchecked exception
:運行期異常,都是java.lang.RuntimeException
的子類,可以不出力
2.1異常類的繼承結構
那我們如何能區分哪些異常屬於編譯期異常,哪些屬於運行期異常呢?
問題3:try…catch捕獲異常時的順序問題
異常範圍大的放下面,範圍小的放前面
1問題
- 下述代碼,編譯能否通過
public class ExceptionTest2 {
public void doSomething01() throws IOException{
System.out.println("do");
}
public static void main(String[] args) {
ExceptionTest2 test = new ExceptionTest2();
try {
test.doSomething01();
} catch (Exception e) {
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}
-
不能
-
第一個
catch
是所有異常類的父類,不管try
中發生何種異常都會進入到第一個catch
的代碼塊中 -
而只要進入了一個
catch
後面所有的catch
就不會再被進入了,所有發生了編譯錯誤 -
當使用多個
catch
來捕獲異常的時候一定要注意範圍問題:異常範圍大的放下面,範圍小的放上面 -
調整順序後,編譯通過
-
一般情況下,我們一般只用一個
catch
來捕獲Exception
類的異常即可