CodeGym /Java Course /Module 1 no mu /異常類型

異常類型

Module 1 no mu
等級 21 , 課堂 3
開放

1.異常類型

所有的異常分為4種類型,它們實際上是相互繼承的類。

Throwable班級

所有異常的基類是類Throwable該類Throwable包含將當前調用堆棧(當前方法的堆棧跟踪)寫入數組的代碼。稍後我們將了解堆棧跟踪是什麼。

throw運算符只能接受從Throwable類派生的對象。儘管理論上您可以編寫類似 的代碼throw new Throwable();,但通常沒有人這樣做。該類的主要目的Throwable是為所有異常提供一個父類。

Error班級

下一個異常類是Error類,直接繼承Throwable類。當出現嚴重問題時, Java 機器會創建該類Error(及其後代)的對象。例如,硬件故障、內存不足等。

通常,作為程序員,在程序中出現這樣的錯誤(應該拋出an 的那種)時,您無能為力:這些錯誤太嚴重了。Error您所能做的就是通知用戶程序正在崩潰和/或將有關錯誤的所有已知信息寫入程序日誌。

Exception班級

ExceptionRuntimeException是針對很多方法運行中出現的常見錯誤。每個拋出的異常的目標是被知道如何正確處理它的塊捕獲。catch

當一個方法由於某種原因不能完成它的工作時,它應該立即通過拋出適當類型的異常來通知調用方法。

換句話說,如果一個變量等於null,該方法將拋出一個NullPointerException。如果將不正確的參數傳遞給該方法,它將拋出一個InvalidArgumentException. 如果該方法不小心被零除,它會拋出一個ArithmeticException.

RuntimeException班級

RuntimeExceptions是 的一個子集Exceptions。我們甚至可以說這RuntimeException是普通異常 ( ) 的輕量級版本Exception——對此類異常施加的要求和限制更少

Exception稍後您將了解 和 之間的區別RuntimeException


2. Throws:檢查異常

所有 Java 異常都分為兩類:已檢查未檢查

所有繼承RuntimeExceptionor的異常Error都被認為是未經檢查的異常 所有其他都是已檢查的異常

重要的!

在引入檢查異常 20 年後,幾乎每個 Java 程序員都認為這是一個錯誤。在流行的現代框架中,95% 的異常都是未經檢查的。幾乎一模一樣照抄Java的C#語言,並沒有加入checked exceptions

已檢查異常未檢查異常之間的主要區別是什麼?

對已檢查的異常有額外的要求。粗略地說,它們是這些:

要求 1

如果一個方法拋出一個已檢查的異常它必須在它的簽名中指明異常的類型這樣,調用它的每個方法都知道這個“有意義的異常”可能會發生在其中。

在關鍵字後的方法參數後面指明檢查異常(不要誤用關鍵字)。它看起來像這樣:throwsthrow

type method (parameters) throws exception

例子:

檢查異常 未經檢查的異常
public void calculate(int n) throws Exception
{
   if (n == 0)
      throw new Exception("n is null!");
}
public void calculate(n)
{
   if (n == 0)
      throw new RuntimeException("n is null!");
}

在右邊的例子中,我們的代碼拋出了一個未經檢查的異常——不需要額外的操作。 在左側的示例中,該方法拋出一個已檢查的異常,因此throws將關鍵字與異常類型一起添加到方法簽名中。

如果一個方法希望拋出多個已檢查的異常,則必須在關鍵字後指定所有這些異常throws,並以逗號分隔。順序並不重要。例子:

public void calculate(int n) throws Exception, IOException
{
   if (n == 0)
      throw new Exception("n is null!");
   if (n == 1)
      throw new IOException("n is 1");
}

要求 2

如果您調用的方法在其簽名中包含已檢查的異常,則您不能忽略它拋出異常的事實。

您必須通過catch為每個異常添加塊來捕獲所有此類異常,或者將它們添加到您的方法的throws子句中。

就好像我們在說,“這些異常非常重要,我們必須捕獲它們。如果我們不知道如何處理它們,那麼必須通知任何可能調用我們方法的人,其中可能會發生此類異常。

例子:

想像一下,我們正在編寫一種方法來創建一個由人類居住的世界。初始人數作為參數傳遞。所以如果人數太少,我們需要添加例外。

創造地球 筆記
public void createWorld(int n) throws EmptyWorldException, LonelyWorldException
{
   if (n == 0)
      throw new EmptyWorldException("There are no people!");
   if (n == 1)
      throw new LonelyWorldException ("There aren't enough people!");
   System.out.println("A wonderful world was created. Population: " + n);
}
該方法可能會拋出兩個已檢查的異常:

  • 空世界異常
  • 孤獨世界異常

此方法調用可以通過 3 種方式處理:

1.不要捕獲任何異常

當方法不知道如何正確處理這種情況時,通常會這樣做。

代碼 筆記
public void createPopulatedWorld(int population)
throws EmptyWorldException, LonelyWorldException
{
   createWorld(population);
}
調用方法不捕獲異常並且必須將它們通知其他人:它將它們添加到自己的throws子句中

2.捕捉一些異常

我們處理我們可以處理的錯誤。但是我們不理解的,我們把它們丟給調用方法。為此,我們需要將他們的名字添加到 throws 子句中:

代碼 筆記
public void createNonEmptyWorld(int population)
throws EmptyWorldException
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
}
調用者只捕獲一個已檢查的異常—— LonelyWorldException. 另一個異常必須添加到它的簽名中,在throws關鍵字之後表明它

3.捕獲所有異常

如果該方法沒有向調用方法拋出異常,那麼調用方法總是確信一切正常。並且它將無法採取任何行動來修復異常情況。

代碼 筆記
public void createAnyWorld(int population)
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
   catch (EmptyWorldException e)
   {
      e.printStackTrace();
   }
}
所有異常都在此方法中捕獲。來電者將確信一切順利。


3.捕獲多個異常

程序員真的很討厭重複代碼。他們甚至提出了相應的開發原則——DRY Don't Repeat Yourself。但是在處理異常時,經常會try出現一個塊後面跟著幾個catch具有相同代碼的塊的情況。

或者可能有 3 個catch塊具有相同的代碼,另外 2 個catch塊具有其他相同的代碼。當您的項目負責任地處理異常時,這是一種標準情況。

從版本 7 開始,在 Java 語言中添加了在單個塊中指定多種異常類型的功能catch。它看起來大致是這樣的:

try
{
   // Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
   // Exception handling code
}

您可以擁有catch任意數量的塊。但是,單個catch塊不能指定相互繼承的異常。也就是說不能寫catch( Exception| RuntimeExceptione),因為RuntimeException類繼承了Exception



留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION