Java的異常、多型要點及抽象類和介面
作者:流浪舟
一、java異常
如下圖,異常分為兩類,錯誤和異常;異常分為執行異常和可查異常。這裡主要掌握異常,因為平時會見的比較多。Exception類在java.lang包下,它是Throwable的子類,同樣的Error類也是其子類。Error 用來指示執行時環境發生的錯誤,例如:JVM 記憶體溢位。一般地,程式不會從錯誤中恢復。異常類有兩個主要的子類:IOException 類和 RuntimeException 類。
Java 根據各個類庫也定義了一些其他的異常,有常用檢查性和非檢查性異常。
異常 | 描述 |
---|---|
ArithmeticException | 當出現異常的運算條件時,丟擲此異常。例如,一個整數"除以零"時,丟擲此類的一個例項。 |
ArrayIndexOutOfBoundsException | 用非法索引訪問陣列時丟擲的異常。如果索引為負或大於等於陣列大小,則該索引為非法索引。 |
ArrayStoreException | 試圖將錯誤型別的物件儲存到一個物件陣列時丟擲的異常。 |
ClassCastException | 當試圖將物件強制轉換為不是例項的子類時,丟擲該異常。 |
IllegalArgumentException | 丟擲的異常表明向方法傳遞了一個不合法或不正確的引數。 |
IllegalMonitorStateException | 丟擲的異常表明某一執行緒已經試圖等待物件的監視器,或者試圖通知其他正在等待物件的監視器而本身沒有指定監視器的執行緒。 |
IllegalStateException | 在非法或不適當的時間呼叫方法時產生的訊號。換句話說,即 Java 環境或 Java 應用程式沒有處於請求操作所要求的適當狀態下。 |
IllegalThreadStateException | 執行緒沒有處於請求操作所要求的適當狀態時丟擲的異常。 |
IndexOutOfBoundsException | 指示某排序索引(例如對陣列、字串或向量的排序)超出範圍時丟擲。 |
NegativeArraySizeException | 如果應用程式試圖建立大小為負的陣列,則丟擲該異常。 |
NullPointerException | 當應用程式試圖在需要物件的地方使用 null |
NumberFormatException | 當應用程式試圖將字串轉換成一種數值型別,但該字串不能轉換為適當格式時,丟擲該異常。 |
SecurityException | 由安全管理器丟擲的異常,指示存在安全侵犯。 |
StringIndexOutOfBoundsException | 此異常由 String 方法丟擲,指示索引或者為負,或者超出字串的大小。 |
UnsupportedOperationException | 當不支援請求的操作時,丟擲該異常。 |
下面的表中列出了在 java.lang 包中的檢查性異常類。
異常 | 描述 |
---|---|
ClassNotFoundException | 應用程式試圖載入類時,找不到相應的類,丟擲該異常。 |
CloneNotSupportedException | 當呼叫 Object 類中的 clone 方法克隆物件,但該物件的類無法實現 Cloneable 介面時,丟擲該異常。 |
IllegalAccessException | 拒絕訪問一個類的時候,丟擲該異常。 |
InstantiationException | 當試圖使用 Class 類中的 newInstance 方法建立一個類的例項,而指定的類物件因為是一個介面或是一個抽象類而無法例項化時,丟擲該異常。 |
InterruptedException | 一個執行緒被另一個執行緒中斷,丟擲該異常。 |
NoSuchFieldException | 請求的變數不存在 |
NoSuchMethodException | 請求的方法不存在 |
異常方法
提一個最常見的,public void printStackTrace(),列印toString()結果和棧層次到System.err,即錯誤輸出流,有點類似錯誤追蹤。
異常捕獲
try/catch 程式碼塊放在異常可能發生的地方,try/catch程式碼塊中的程式碼稱為保護程式碼,使用 try/catch 的語法如下:
try{
// 程式程式碼
}catch(ExceptionName e1){
//Catch 塊
}
可以有多個catch語句,叫多重捕獲。catch 語句包含要捕獲異常型別的宣告,當保護程式碼塊中發生一個異常時,try 後面的 catch 塊就會被檢查。如果發生的異常包含在 catch 塊中,異常會被傳遞到該 catch 塊。
丟擲異常
如果一個方法沒有捕獲到一個檢查性異常,那麼該方法必須使用 throws 關鍵字來宣告。throws 關鍵字放在方法簽名的尾部,也可以使用 throw 關鍵字丟擲一個異常。需要注意的是,如果有必要丟擲多個異常,則可以在後面繼續新增用逗號隔開。
finally關鍵字
finally關鍵字用來建立在 try 程式碼塊後面執行的程式碼塊。無論是否發生異常,finally 程式碼塊中的程式碼總會被執行。在finally程式碼塊中,可以執行清理型別等收尾善後性質的語句。finally 程式碼塊出現在 catch 程式碼塊最後,語法如下:
try{
// 程式程式碼
}catch(異常型別1 異常的變數名1){
// 程式程式碼
}catch(異常型別2 異常的變數名2){
// 程式程式碼
}finally{
// 程式程式碼
}
二、被搞糊塗的多型
存在必要條件:
- 繼承
- 重寫
- 父類引用指向子類物件
比如:
Parent p = new Child();
注意(容易忘,容易搞糊塗):當使用多型方式呼叫方法時,首先檢查父類中是否有該方法,如果有,則去呼叫子類的同名方法,但不能呼叫子類獨有的方法。多型的好處是可以使程式有良好的擴充套件,並可以對所有類的物件進行通用處理。
多型的實現方式:
方式一:重寫:
方式二:介面
方式三:抽象類和抽象方法
三、Abstract抽象類和介面
抽象類:
抽象類和其他普通類沒什麼區別,除了不能例項化外,其他功能都還好。由於抽象類不能例項化物件,所以抽象類必須被繼承,才能被使用。在Java中,抽象類表示的是一種繼承關係,一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。
宣告抽象方法會造成以下結果:
- 如果一個類包含抽象方法,那麼該類必須是抽象類。
- 任何子類必須重寫父類的抽象方法,或者宣告自身為抽象類。
需要注意:抽象類不一定有抽象方法,而有抽象方法一定是抽象類; 構造方法,類方法(用static修飾的方法)不能宣告為抽象方法;抽象類的子類必須給出抽象類中的抽象方法的具體實現,除非該子類也是抽象類。
介面:interface
介面並不是類,類描述物件的屬性和方法,介面則包含類要實現的方法。除非實現介面的類是抽象類,否則該類要定義介面中的所有方法。介面沒有構造方法,同樣無法被例項化。一個實現介面的類,必須實現介面內所描述的所有方法,否則就必須宣告為抽象類。
介面與介面之間則是通過繼承來關聯,支援多繼承!
import java.lang.*;
public interface NameOfInterface extends a,b,c{//a,b,c介面
public void w();
public void v();
public void e(int period);
public void o(int ot);
//任何型別 final, static 欄位
//抽象方法(隱式)
}
介面特性:
- 介面中每一個方法是隱式抽象的,指定為public abstract(只能是public abstract,其他修飾符都會報錯)
- 介面中可以含有變數,但是會被隱式的指定為public static final 變數(並且只能是public)
介面中每一個方法也是隱式抽象的,宣告時不需要abstract關鍵字,介面中的方法都是公有的public。
抽象類和介面的區別:
- 抽象類中的方法可以有方法體,但是介面中的方法不行(jdk1.8)。
- 抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是 public static final 型別的。
- 介面中不能含有靜態程式碼塊以及靜態方法(用static修飾的方法),而抽象類是可以有靜態程式碼塊和靜態方法。
- 一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。
注:JDK 1.8 以後,接口裡可以有靜態方法和方法體了
介面的實現:implements
與抽象類不同,當類實現介面的時候,類要實現介面中所有的方法,否則,類必須宣告為抽象的類。
public class Mydog implements Animal,dog{
public void eat(){
System.out.println("Mydog eats");
}
}
重寫介面中宣告的方法時,需要注意以下:
- 類在實現介面的方法時,不能丟擲強制性異常,只能在介面中,或者繼承介面的抽象類中丟擲該強制性異常。
- 類在重寫方法時要保持一致的方法名,並且應該保持相同或者相相容的返回值型別。
- 如果實現介面的類是抽象類,那麼就沒必要實現該介面的方法。
在實現介面的時候,也要注意:
- 一個類可以同時實現多個介面
- 一個類只能繼承一個類,但是能實現多個介面
公眾號:小碼之光
個人站點 https://index.maliaoblog.cn