JNI完全指南(二)——類與異常

weixin_33785972發表於2016-11-15

標籤(空格分隔): JNI完全指南

版本:1
作者:陳小默
宣告:禁止商業,禁止轉載

釋出於作業部落簡書CSDN部落格


上一篇:JNI完全指南(一)——資料型別


[toc]


二、類與異常

2.1 類

2.1.1 載入類

我們可以使用下列方法通過類定義去載入一個類。

jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
const jbyte *buf, jsize bufLen);

  • name:類的全名,必須是被UTF-8編碼過的字串。
  • loader:類載入器。
  • buf:包含類資料的緩衝區。這個緩衝區包含一個原始類資料,並且要求這個類在呼叫此方法前沒有被JVM所引用。
  • bufLen:緩衝區長度。
  • return:java類物件。發生錯誤時返回NULL。

其間可能會丟擲如下異常:

  • ClassFormatError:類格式錯誤。
  • ClassCircularityError:類迴圈錯誤。如果一個類或介面繼承了自己。
  • OutOfMemoryError:記憶體溢位。
  • SecurityException:安全性錯誤。如果呼叫者試圖在Java包結構上定義一個類。

2.1.2 查詢一個類

通過以下方法我們可以通過類名查詢到一個類。

jclass FindClass(JNIEnv *env, const char *name);

  • name:類的全名。使用UTF-8編碼,其中分隔符使用/表示。
  • return:java類物件。發生錯誤時返回NULL。

其間可能會丟擲如下異常:

  • ClassFormatError
  • ClassCircularityError
  • NoClassDefFoundError:沒有找到相應的類物件。
  • OutOfMemoryError

2.1.3 獲取父類

通過如下方法我們可以獲取到一個類的父類的類物件

jclass GetSuperclass(JNIEnv *env, jclass clazz);

  • clazz:需要查詢的類物件。
  • return:clazz的父類類物件。如果clazz是Object類物件或者clazz是介面的類資訊,返回NULL。

2.1.4 型別轉換

當我們將一個物件從一種型別轉換為另一種型別之前,我們必須確保這種型別轉換是安全的。我們可以通過如下方法去判斷這兩種型別是否可以互相轉換。

jboolean IsAssignableFrom(JNIEnv *env, jclass clazz1,
jclass clazz2);

  • clazz1:原始型別。
  • class2:目標型別。
  • return:當前型別轉換是否安全。

2.2 異常

本節內容介紹JNI中異常操作相關的方法。C++中可以使用其內部的異常機制,但是這套機制丟擲的異常並不會傳遞給我們的JVM,所以為了你補這個缺點,JNI實現了一套可以和JVM進行交流的異常機制。

2.2.1 丟擲已有的異常物件

我們可以通過如下方法丟擲一個異常。

jint Throw(JNIEnv *env, jthrowable obj);

  • obj:一個java.lang.Throwable物件。
  • return:異常丟擲結果。0表示異常正常丟擲到JVM,否則異常丟擲失敗。

2.2.2 丟擲一個新異常物件

在2.3.1中我們可以丟擲一個已有的異常物件。那麼對於我們想丟擲的異常可以採用如下方法。

jint ThrowNew(JNIEnv *env, jclass clazz,
const char *message);

  • clazz:待丟擲的異常類。
  • message:異常訊息。要求UTF-8編碼。
  • return:異常丟擲結果。0表示異常正常丟擲到JVM,否則異常丟擲失敗。

2.2.3 獲取JVM丟擲的異常

如果我們需要知道我們之前的操作是否存在JVM丟擲的異常時,我們可以呼叫如下方法獲取異常物件,注意:即使我們獲取到了異常物件,這個異常仍然在JVM中存在,直到我們呼叫ExceptionClear方法清空異常。

jthrowable ExceptionOccurred(JNIEnv *env);

  • return:當前發生的異常物件。如果沒有異常丟擲則返回NULL。

2.2.4 輸出錯誤日誌

當我們攔截到一個異常,我們可以使用如下方法列印錯誤棧中的內容。就像Java中的printStackTrace:

void ExceptionDescribe(JNIEnv *env);

2.2.5 清空異常資訊

呼叫以下方法可以清空當前產生的全部異常資訊

void ExceptionClear(JNIEnv *env);

2.2.6 產生一個嚴重的錯誤

對於上述異常,我們可以產生也可以攔截。但是如果發生了一些錯誤導致我們的程式無法再正常執行下去了,則可以傳送一個錯誤資訊給JVM,此時程式將被終止。

void FatalError(JNIEnv *env, const char *msg);

  • msg:錯誤資訊。UTF-8。

2.2.7 檢查是否存在異常資訊

我們可以通過以下方法檢視當前有沒有異常產生。

jboolean ExceptionCheck(JNIEnv *env);

  • return:是否存在異常資訊。

下一篇:JNI完全指南(三)——引用型別


參考文獻:
[1]ORACLE guides for JNI——Chapter 4: JNI Functions

相關文章