首頁 > 軟體

Java特性之註解和異常 Throwable

2022-06-19 14:00:52

註解

作用

註解是JDK1.5版本開始引入的一個特性,用於對程式碼進行說明,可以對包、類、介面、欄位、方法引數、區域性變數等進行註解。它主要的作用有以下四方面:

  • 生成檔案,通過程式碼裡標識的後設資料生成javadoc檔案。
  • 編譯檢查,通過程式碼裡標識的後設資料讓編譯器在編譯期間進行檢查驗證。
  • 編譯時動態處理,編譯時通過程式碼裡標識的後設資料動態處理,例如動態生成程式碼。
  • 執行時動態處理,執行時通過程式碼裡標識的後設資料動態處理,例如使用反射注入範例。

註解的常見分類

  • Java自帶的標準註解,包括@Override@Deprecated@SuppressWarnings,分別用於標明重寫某個方法、標明某個類或方法過時、標明要忽略的警告,用這些註解標明後編譯器就會進行檢查。
  • 元註解,元註解是用於定義註解的註解,包括@Retention@Target@Inherited@Documented
    • @Retention用於標明註解被保留的階段
    • @Target用於標明註解使用的範圍
    • @Inherited用於標明註解可繼承
    • @Documented用於標明是否生成javadoc檔案
  • 自定義註解,可以根據自己的需求定義註解,並可用元註解對自定義註解進行註解。

異常

Java異常類層次結構

  • Throwable 是 Java 語言中所有錯誤與異常的超類。
    • Error 類及其子類:程式中無法處理的錯誤,表示執行應用程式中出現了嚴重的錯誤。
    • Exception 程式本身可以捕獲並且可以處理的異常。Exception 這種異常又分為兩類:執行時異常和編譯時異常。

執行時異常:

都是RuntimeException類及其子類異常,如NullPointerException(空指標異常)、IndexOutOfBoundsException(下標越界異常)等,這些異常是不檢查異常,程式中可以選擇捕獲處理,也可以不處理。這些異常一般是由程式邏輯錯誤引起的,程式應該從邏輯角度儘可能避免這類異常的發生。

執行時異常的特點是Java編譯器不會檢查它,也就是說,當程式中可能出現這類異常,即使沒有用try-catch語句捕獲它,也沒有用throws子句宣告丟擲它,也會編譯通過。

非執行時異常 (編譯異常)

是RuntimeException以外的異常,型別上都屬於Exception類及其子類。從程式語法角度講是必須進行處理的異常,如果不處理,程式就不能編譯通過。如IOException、SQLException等以及使用者自定義的Exception異常,一般情況下不自定義檢查異常。

可查的異常(checked exceptions)和不可查的異常(unchecked exceptions)區別

可查異常(編譯器要求必須處置的異常):

正確的程式在執行中,很容易出現的、情理可容的異常狀況。可查異常雖然是異常狀況,但在一定程度上它的發生是可以預計的,而且一旦發生這種異常狀況,就必須採取某種方式進行處理。

除了RuntimeException及其子類以外,其他的Exception類及其子類都屬於可查異常。這種異常的特點是Java編譯器會檢查它,也就是說,當程式中可能出現這類異常,要麼用try-catch語句捕獲它,要麼用throws子句宣告丟擲它,否則編譯不會通過。

不可查異常(編譯器不要求強制處置的異常)

包括執行時異常(RuntimeException與其子類)和錯誤(Error)。

throw和throws的區別?

異常的申明(throws):

在Java中,當前執行的語句必屬於某個方法,Java直譯器呼叫main方法執行開始執行程式。若方法中存在檢查異常,如果不對其捕獲,那必須在方法頭中顯式宣告該異常,以便於告知方法呼叫者此方法有異常,需要進行處理。 在方法中宣告一個異常,方法頭中使用關鍵字throws,後面接上要宣告的異常。若宣告多個異常,則使用逗號分割。如下所示:

public static void method() throws IOException, FileNotFoundException{ //something statements }

異常的丟擲(throw):

如果程式碼可能會引發某種錯誤,可以建立一個合適的異常類範例並丟擲它,這就是丟擲異常。

如下所示:

public static double method(int value) { if(value == 0) { throw new ArithmeticException("引數不能為0"); //丟擲一個執行時異常 } return 5.0 / value; }

Java 7 的 try-with-resource?

如果你的資源實現了 AutoCloseable 介面,你可以使用這個語法。大多數的 Java 標準資源都繼承了這個介面。當你在 try 子句中開啟資源,資源會在 try 程式碼塊執行後或例外處理後自動關閉。

    File file = new File("./tmp.txt");
    try (FileInputStream inputStream = new FileInputStream(file);) {
        // use the inputStream to read a file
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
}

異常的底層?

提到JVM處理異常的機制,就需要提及Exception Table,以下稱為異常表。我們暫且不急於介紹異常表,先看一個簡單的 Java 處理異常的小例子。

   try {
       testNPE();
   } catch (Exception e) {
       e.printStackTrace();
   }
}

異常表中包含了一個或多個例外處理者(Exception Handler)的資訊,這些資訊包含如下

  • from 可能發生異常的起始點
  • to 可能發生異常的結束點
  • target 上述from和to之前發生異常後的例外處理者的位置
  • type 例外處理者處理的異常的類資訊

反射

什麼是反射?

JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。

反射的使用

在Java中,Class類與java.lang.reflect類庫一起對反射技術進行了全力的支援。在反射包中,我們常用的類主要有Constructor類表示的是Class 物件所表示的類的構造方法,利用它可以在執行時動態建立物件、Field表示Class物件所表示的類的成員變數,通過它可以在執行時動態修改成員變數的屬性值(包含private)、Method表示Class物件所表示的類的成員方法,通過它可以動態呼叫物件的方法(包含private)

Class類物件的獲取:

    @Test
    public void classTest() throws Exception {
        // 獲取Class物件的三種方式
        logger.info("根據類名:  t" + User.class);
        logger.info("根據物件:  t" + new User().getClass());
        logger.info("根據全限定類名:t" + Class.forName("com.test.User"));
        // 常用的方法
        logger.info("獲取全限定類名:t" + userClass.getName());
        logger.info("獲取類名:t" + userClass.getSimpleName());
        logger.info("範例化:t" + userClass.newInstance());
    }
  • Constructor類及其用法
  • Field類及其用法
  • Method類及其用法

getName、getCanonicalName與getSimpleName的區別?

  • getSimpleName:只獲取類名
  • getName:類的全限定名,jvm中Class的表示,可以用於動態載入Class物件,例如Class.forName。
  • getCanonicalName:返回更容易理解的表示,主要用於輸出(toString)或log列印,大多數情況下和getName一樣,但是在內部類、陣列等型別的表示形式就不同了。

到此這篇關於Java特性之註解和異常 Throwable的文章就介紹到這了,更多相關Java 註解和異常 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com