SlideShare a Scribd company logo
1 of 55
Download to read offline
1
例外處理
學習目標
• 使用try、catch處理例外
• 認識例外繼承架構
• 認識throw、throws使用時機
• 運用finally關閉資源
• 使用自動關閉資源語法
• 認識AutoCloseable介面
2
使用try、catch
3
• 嘗試(try)執行程式並捕捉(catch)
4
• 有時錯誤可以在捕捉處理之後,繼續程式正
常執行流程
5
例外繼承架構
6
7
• 受檢例外(Checked Exception)
• API設計者實作某方法時,某些條件下會引
發錯誤,而且認為呼叫者有能力處理錯誤,
因此宣告拋出受檢例外,要求編譯器提醒呼
叫者必須明確處理錯誤
8
• RuntimeException衍生出來的類別實例
,代表API設計者實作某方法時,某些條件
下會引發錯誤,而且認為應該在呼叫方法前
做好檢查,以避免引發錯誤
9
10
11
• 如果父類別例外在子類別例外前被捕捉,子
類別例外的catch區塊將不會執行
12
• 數個型態的catch區塊做相同的事情
13
• catch括號中列出的例外不得有繼承關係
14
要抓還是要拋?
15
• 這個程式庫會用在文字模式中嗎?
16
• 當時環境無法處理的部份,可以再度拋出例
外,由呼叫方法的客戶端處理
17
• 在JDK7之前會出錯:
18
• 父類別某個方法宣告throws某些例外,子類
別重新定義該方法時可以:
– 不宣告throws任何例外。
– 可throws父類別該方法宣告的某些例外。
– 可throws父類別該方法宣告例外之子類別。
• 不可以:
– throws父類別方法未宣告的其他例外。
– throws父類別方法宣告例外之父類別。
19
貼心還是造成麻煩?
• Java是唯一採用受檢例外的語言:
– 文件化
– 提供編譯器資訊
• 有些錯誤引發的例外,你根本無力處理
• 最好的方式是將例外傳播至使用者介面呈現
20
• 除了將捕捉到的例外直接拋出,也可以考慮
為應用程式自訂專屬例外類別
21
• 一個基本的例子是這樣的:
22
• 這是客戶端可以處理的例外嗎?還是客戶端
沒有準備好前置條件就呼叫方法,才引發的
例外?
23
• 有些開發者設計程式庫時,會選擇完全使用
非受檢例外,給予開發者較大彈性來面對例
外(開發者也就需要更多的經驗才能掌握)
• 隨著應用程式的演化,例外也可以考慮演化
,也許一開始是設計為受檢例外
• 然而隨著應用程式堆疊的加深…將受檢例外
演化為非受檢例外,也許就有其必要。
24
認識堆疊追蹤
25
• 想取得個別的堆疊追蹤元素進行處理,可以
使用getStackTrace()
26
• 要善用堆疊追蹤,前題是程式碼中不可有私
吞例外的行為
27
• 對例外做了不適當的處理,或顯示了不正確
的資訊
• 有些開發者為了省麻煩
28
• 使用throw重拋例外時,例外的追蹤堆疊起
點,仍是例外的發生根源
29
30
• 想讓例外堆疊起點為重拋例外的地方,可以
使用fillInStackTrace()
31
32
關於assert
• JDK 1.4以後提供assert語法
• 在執行java指令時,指定-
enableassertions或是-ea引數
33
• 何時該使用斷言呢?
– 斷言客戶端呼叫方法前,已經準備好某些前置條
件。
– 斷言客戶端呼叫方法後,會有方法承諾的結果。
– 斷言物件某時間點的狀態。
– 使用斷言取代註解。
– 斷言程式流程中絕對不會執行到的程式碼部份。
34
35
36
• checkGreaterThanZero()是種前置條件
檢查
• 如果程式上線後就不再需要這種檢查的話,
可以用assert取代
37
38
使用finally
• 何時關閉資源呢?如下撰寫並不是很正確:
39
• 無論如何,最後一定要執行關閉資源
40
• finally區塊會先執行完畢後,再將值
return
41
嘗試關閉資源
42
• 編譯器蜜糖
43
44
45
• 想在發生FileNotFoundException時顯
示堆疊追蹤訊息:
46
47
48
• 在JDK8或JDK7中會編譯錯誤:
• JDK9以後,只要變數是final或等效於
final,就可以通過編譯
49
java.lang.AutoCloseable
50
51
• 實作AutoCloseable介面,就可以套用嘗
試關閉資源語法
52
• 可以關閉兩個以上的物件資源,以分號區隔
53
54
55

More Related Content

What's hot

What's hot (12)

4. 流程語法與函式
4. 流程語法與函式4. 流程語法與函式
4. 流程語法與函式
 
11, exceptions
11, exceptions11, exceptions
11, exceptions
 
Java_04:例外異常處理機制
Java_04:例外異常處理機制Java_04:例外異常處理機制
Java_04:例外異常處理機制
 
RSpec & TDD Tutorial
RSpec & TDD TutorialRSpec & TDD Tutorial
RSpec & TDD Tutorial
 
並行與平行
並行與平行並行與平行
並行與平行
 
6. 非同步設計
6. 非同步設計6. 非同步設計
6. 非同步設計
 
輸入輸出
輸入輸出輸入輸出
輸入輸出
 
並行、平行與非同步
並行、平行與非同步並行、平行與非同步
並行、平行與非同步
 
執行緒與並行API
執行緒與並行API執行緒與並行API
執行緒與並行API
 
9. meta-programming
9. meta-programming9. meta-programming
9. meta-programming
 
JavaScript 教程
JavaScript 教程JavaScript 教程
JavaScript 教程
 
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
 

More from Justin Lin

More from Justin Lin (20)

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring Boot
 
Ch13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/SecurityCh13 整合 Spring MVC/Security
Ch13 整合 Spring MVC/Security
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMail
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTL
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSP
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 Servlet
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題
 
13.並行、平行與非同步
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換
 
9. 資料結構
9. 資料結構9. 資料結構
9. 資料結構
 

CH08:例外處理