[TOC]
# 異常
## 異常的繼承體系
在Java中使用Exception類來描述異常

Exception 類及其子類是 Throwable 的一種形式,它用來表示java程序中可能會產生的異常,并要求對產生的異常進行合理的異常處理。
我們可以發現Exception有繼承關系,它的父類是Throwable。Throwable是Java 語言中所有錯誤或異常的超類。

另外,在異常Exception類中,有一個子類要特殊說明一下,RuntimeException子類,RuntimeException及其它的子類只能在Java程序運行過程中出現
異常繼承體系總結:
Throwable: 它是所有錯誤與異常的超類(祖宗類)
|- Error 錯誤
|- Exception 編譯期異常,進行編譯JAVA程序時出現的問題
|- RuntimeException 運行期異常, JAVA程序運行過程中出現的問題
## 拋出異常throw
在java中,提供了一個throw關鍵字,它用來拋出一個指定的異常對象。那么,拋出一個異常具體如何操作呢?
* 1,創建一個異常對象。封裝一些提示信息(信息可以自己編寫)。
* 2,需要將這個異常對象告知給調用者。怎么告知呢?怎么將這個異常對象傳遞到調用者處呢?通過關鍵字throw就可以完成。throw 異常對象;
throw用在方法內,用來拋出一個異常對象,將這個異常對象傳遞到調用者處,并結束當前方法的執行。
使用格式:
~~~
throw new 異常類名(參數);
~~~
例如:
~~~
throw new NullPointerException("要訪問的arr數組不存在");
throw new ArrayIndexOutOfBoundsException("該索引在數組中不存在,已超出范圍");
~~~
* 下面是異常類ArrayIndexOutOfBoundsException與NullPointerException的構造方法

## 聲明異常throws
聲明:將問題標識出來,報告給調用者。如果方法內通過throw拋出了編譯時異常,而沒有捕獲處理(稍后講解該方式),那么必須通過throws進行聲明,讓調用者去處理。
聲明異常格式:
~~~
修飾符 返回值類型 方法名(參數) throws 異常類名1,異常類名2… { }
~~~
## 捕獲異常try…catch…finally
捕獲:Java中對異常有針對性的語句進行捕獲,可以對出現的異常進行指定方式的處理
捕獲異常格式:
~~~
try {
//需要被檢測的語句。
}
catch(異常類 變量) { //參數。
//異常的處理語句。
}
finally {
//一定會被執行的語句。
}
~~~
try:該代碼塊中編寫可能產生異常的代碼。
catch:用來進行某種異常的捕獲,實現對捕獲到的異常進行處理。
finally:有一些特定的代碼無論異常是否發生,都需要執行。另外,因為異常會引發程序跳轉,導致有些語句執行不到。而finally就是解決這個問題的,在finally代碼塊中存放的代碼都是一定會被執行的。
## 運行時期異常
* RuntimeException和他的所有子類異常,都屬于運行時期異常。NullPointerException,ArrayIndexOutOfBoundsException等都屬于運行時期異常.
* 運行時期異常的特點:
* 方法中拋出運行時期異常,方法定義中無需throws聲明,調用者也無需處理此異常
* 運行時期異常一旦發生,需要程序人員修改源代碼.
## 異常在方法重寫中細節
* 子類覆蓋父類方法時,如果父類的方法聲明異常,子類只能聲明父類異常或者該異常的子類,或者不聲明。
例如:
~~~
class Fu {
public void method () throws RuntimeException {
}
}
class Zi extends Fu {
public void method() throws RuntimeException { } //拋出父類一樣的異常
//public void method() throws NullPointerException{ } //拋出父類子異常
}
~~~
* 當父類方法聲明多個異常時,子類覆蓋時只能聲明多個異常的子集。
例如:
~~~
class Fu {
public void method () throws NullPointerException, ClassCastException{
}
}
class Zi extends Fu {
public void method()throws NullPointerException, ClassCastException { } public void method() throws NullPointerException{ } //拋出父類異常中的一部分
public void method() throws ClassCastException { } //拋出父類異常中的一部分
}
~~~
* 當被覆蓋的方法沒有異常聲明時,子類覆蓋時無法聲明異常的。
例如:
~~~
class Fu {
public void method (){
}
}
class Zi extends Fu {
public void method() throws Exception { }//錯誤的方式
}
~~~
舉例:父類中會存在下列這種情況,接口也有這種情況
問題:接口中沒有聲明異常,而實現的子類覆蓋方法時發生了異常,怎么辦?
答:無法進行throws聲明,只能catch的捕獲。萬一問題處理不了呢?catch中繼續throw拋出,但是只能將異常轉換成RuntimeException子類拋出
~~~
interface Inter {
public abstract void method();
}
class Zi implements Inter {
public void method(){ //無法聲明 throws Exception
int[] arr = null;
if (arr == null) {
//只能捕獲處理
try{
throw new Exception(“哥們,你定義的數組arr是空的!”);
} catch(Exception e){
System.out.println(“父方法中沒有異常拋出,子類中不能拋出Exception異常”);
//我們把異常對象e,采用RuntimeException異常方式拋出
throw new RuntimeException(e);
}
}
}
}
~~~
## 異常中常用方法
在Throwable類中為我們提供了很多操作異常對象的方法,常用的如下

* getMessage方法:返回該異常的詳細信息字符串,即異常提示信息
* toString方法:返回該異常的名稱與詳細信息字符串
* printStackTrace:在控制臺輸出該異常的名稱與詳細信息字符串、異常出現的代碼位置
~~~
try {
Person p= null;
if (p==null) {
throw new NullPointerException(“出現空指針異常了,請檢查對象是否為null”);
}
} catch (NullPointerException e) {
String message = e.getMesage();
System.out.println(message );
String result = e.toString();
System.out.println(result);
e.printStackTrace();
}
~~~
# 自定義異常
java中所有的異常類,都是繼承Throwable,或者繼承Throwable的子類。這樣該異常才可以被throw拋出。
說明這個異常體系具備一個特有的特性:可拋性:即可以被throw關鍵字操作。
并且查閱異常子類源碼,發現每個異常中都調用了父類的構造方法,把異常描述信息傳遞給了父類,讓父類幫我們進行異常信息的封裝。
例如NullPointerException異常類源代碼:
~~~
public class NullPointerException extends RuntimeException {
public NullPointerException() {
super();//調用父類構造方法
}
public NullPointerException(String s) {
super(s);//調用父類具有異常信息的構造方法
}
}
~~~
* 自定義異常繼承Exception演示
~~~
class MyException extends Exception{
/*
為什么要定義構造函數,因為看到Java中的異常描述類中有提供對異常對象的初始化方法。
*/
public MyException(){
super();
}
public MyException(String message) {
super(message);// 如果自定義異常需要異常信息,可以通過調用父類的帶有字符串參數的構造函數即可。
}
}
~~~
* 自定義異常繼承RuntimeException演示
~~~
class MyException extends RuntimeException{
/*
為什么要定義構造函數,因為看到Java中的異常描述類中有提供對異常對象的初始化方法。
*/
MyException(){
super();
}
MyException(String message) {
super(message);// 如果自定義異常需要異常信息,可以通過調用父類的帶有字符串參數的構造函數即可。
}
}
~~~
- 基礎
- 編譯和安裝
- scanner類(鍵盤錄入)
- Random類(隨機數)
- 數組
- 方法
- 類
- ArrayList集合
- char與int
- eclipse
- IDEA
- 變量與常量
- 常用API
- String,StringBuffer,StringBuilder
- 正則,Date,DateFormat,Calendar
- 包裝類,System,Math,Arrays,BigInteger,BigDecimal
- 集合,迭代器,增強for,泛型
- List,set,判斷集合唯一
- map,Entry,HashMap,Collections
- 異常
- IO
- File
- 遞歸
- 字節流
- 字符流
- IO流分類
- 轉換流
- 緩沖流
- 流的操作規律
- properties
- 序列化流與反序列化流
- 打印流
- commons-IO
- IO流總結
- 多線程
- 線程池
- 線程安全
- 線程同步
- 死鎖
- lock接口
- ThreadLoad
- 等待喚醒機制
- 線程狀態
- jdbc
- DBUtils
- 連接池DBCP
- c3p0連接池
- 網絡編程
- 多線程socket上傳圖片
- 反射
- xml
- 設計模式
- 裝飾器模式
- web service
- tomcat
- Servlet
- response
- request
- session和cookie
- JSP
- EL
- JSTL
- 事務
- 監聽器Listener
- 過濾器Filter
- json
- linux安裝軟件
- 反射詳解
- 類加載器和注解
- 動態代理
- jedis
- Hibernate
- 簡介
- 創建映射文件
- Hibernate核心配置文件
- 事務和增刪改查
- HibernateUtils
- 持久化對象的三種狀態
- 檢索方式
- query
- Criteria
- SQLQuery
- 持久化類
- 主鍵生成策略
- 緩存
- 事務管理
- 關系映射
- 注解
- 優化
- struts2
- 搭建
- 配置詳解
- Action
- 結果跳轉方式
- 訪問ServletAPI方式
- 如何獲得參數
- OGNL表達式
- valueStack 值棧
- Interceptor攔截器
- spring
- 導包
- IOC和DI
- Bean獲取與實例化
- Bean屬性注入
- spring注解
- 注解分層
- junit整合
- aop
- 動態代理實現
- cglib代理實現
- aop名詞
- spring的aop
- aop-xml詳解
- aop-注解詳解
- 代理方式選擇
- jdbcTemplate
- spring事務管理
- 回滾注意
- 事務傳播屬性
- MyBatis
- MyBatis簡介
- 入門程序
- 與jdbc hibernate不同
- 原始Dao開發
- Mapper動態代理方式
- SqlMapConfig.xml配置文件
- 輸入參數pojo包裝類
- resultMap
- 動態sql
- 一對一關聯
- 一對多
- 整合spring
- 逆向工程
- maven
- maven簡介
- 倉庫
- maven目錄結構
- maven常用命令
- 生命周期
- eclipse中maven插件
- 入門程序
- 整合struct
- 依賴范圍
- 添加插件
- idea配置
- jar包沖突
- 分模塊開發
- 構建可執行的jar包(包含依賴jar包)
- springMVC
- 處理流程
- java面試
- java版本升級
- java1-8版本變更
- java9新特性
- 鎖
- java資料
- idea
- jdk版本切換
- log4j
- 入門實例
- 基本使用方法
- Web中使用Log4j
- spring中使用log4j
- java代碼優化