1. 程式人生 > >Java本機介面規範內容 第4章:JNI函式

Java本機介面規範內容 第4章:JNI函式

本章作為JNI函式的參考部分。 它提供了所有JNI功能的完整列表。 它還提供了JNI函式表的確切佈局。

請注意使用術語“必須”來描述對JNI程式設計師的限制。 例如,當您看到某個JNI函式必須接收非NULL物件時,您有責任確保不將NULL傳遞給該JNI函式。 因此,JNI實現不需要在該JNI函式中執行NULL指標檢查。

本章的一部分改編自Netscape的JRI文件。

參考材料按其用法分組。 參考部分由以下功能區域組成:

目錄

介面功能表

版本資訊

常量

班級操作

例外

致命錯誤

全球參考

本地參考

弱全球參考

物件操作

字串操作

陣列操作

監控操作

NIO支援

反思支援

介面功能表

可以通過JNIEnv引數以固定偏移量訪問每個函式。 JNIEnv型別是指向儲存所有JNI函式指標的結構的指標。 它的定義如下:

typedef const struct JNINativeInterface *JNIEnv;

VM初始化函式表,如以下程式碼示例所示。 請注意,前三個條目保留用於將來與COM的相容性。 此外,我們在函式表的開頭附近保留了一些額外的NULL

條目,因此,例如,可以在FindClass之後而不是在表的末尾新增與類相關的未來JNI操作。

請注意,函式表可以在所有JNI介面指標之間共享。

const struct JNINativeInterface ... = {

    NULL,
    NULL,
    NULL,
    NULL,
    GetVersion,

    DefineClass,
    FindClass,

    FromReflectedMethod,
    FromReflectedField,
    ToReflectedMethod,

    GetSuperclass,
    IsAssignableFrom,

    ToReflectedField,

    Throw,
    ThrowNew,
    ExceptionOccurred,
    ExceptionDescribe,
    ExceptionClear,
    FatalError,

    PushLocalFrame,
    PopLocalFrame,

    NewGlobalRef,
    DeleteGlobalRef,
    DeleteLocalRef,
    IsSameObject,
    NewLocalRef,
    EnsureLocalCapacity,

    AllocObject,
    NewObject,
    NewObjectV,
    NewObjectA,

    GetObjectClass,
    IsInstanceOf,

    GetMethodID,

    CallObjectMethod,
    CallObjectMethodV,
    CallObjectMethodA,
    CallBooleanMethod,
    CallBooleanMethodV,
    CallBooleanMethodA,
    CallByteMethod,
    CallByteMethodV,
    CallByteMethodA,
    CallCharMethod,
    CallCharMethodV,
    CallCharMethodA,
    CallShortMethod,
    CallShortMethodV,
    CallShortMethodA,
    CallIntMethod,
    CallIntMethodV,
    CallIntMethodA,
    CallLongMethod,
    CallLongMethodV,
    CallLongMethodA,
    CallFloatMethod,
    CallFloatMethodV,
    CallFloatMethodA,
    CallDoubleMethod,
    CallDoubleMethodV,
    CallDoubleMethodA,
    CallVoidMethod,
    CallVoidMethodV,
    CallVoidMethodA,

    CallNonvirtualObjectMethod,
    CallNonvirtualObjectMethodV,
    CallNonvirtualObjectMethodA,
    CallNonvirtualBooleanMethod,
    CallNonvirtualBooleanMethodV,
    CallNonvirtualBooleanMethodA,
    CallNonvirtualByteMethod,
    CallNonvirtualByteMethodV,
    CallNonvirtualByteMethodA,
    CallNonvirtualCharMethod,
    CallNonvirtualCharMethodV,
    CallNonvirtualCharMethodA,
    CallNonvirtualShortMethod,
    CallNonvirtualShortMethodV,
    CallNonvirtualShortMethodA,
    CallNonvirtualIntMethod,
    CallNonvirtualIntMethodV,
    CallNonvirtualIntMethodA,
    CallNonvirtualLongMethod,
    CallNonvirtualLongMethodV,
    CallNonvirtualLongMethodA,
    CallNonvirtualFloatMethod,
    CallNonvirtualFloatMethodV,
    CallNonvirtualFloatMethodA,
    CallNonvirtualDoubleMethod,
    CallNonvirtualDoubleMethodV,
    CallNonvirtualDoubleMethodA,
    CallNonvirtualVoidMethod,
    CallNonvirtualVoidMethodV,
    CallNonvirtualVoidMethodA,

    GetFieldID,

    GetObjectField,
    GetBooleanField,
    GetByteField,
    GetCharField,
    GetShortField,
    GetIntField,
    GetLongField,
    GetFloatField,
    GetDoubleField,
    SetObjectField,
    SetBooleanField,
    SetByteField,
    SetCharField,
    SetShortField,
    SetIntField,
    SetLongField,
    SetFloatField,
    SetDoubleField,

    GetStaticMethodID,

    CallStaticObjectMethod,
    CallStaticObjectMethodV,
    CallStaticObjectMethodA,
    CallStaticBooleanMethod,
    CallStaticBooleanMethodV,
    CallStaticBooleanMethodA,
    CallStaticByteMethod,
    CallStaticByteMethodV,
    CallStaticByteMethodA,
    CallStaticCharMethod,
    CallStaticCharMethodV,
    CallStaticCharMethodA,
    CallStaticShortMethod,
    CallStaticShortMethodV,
    CallStaticShortMethodA,
    CallStaticIntMethod,
    CallStaticIntMethodV,
    CallStaticIntMethodA,
    CallStaticLongMethod,
    CallStaticLongMethodV,
    CallStaticLongMethodA,
    CallStaticFloatMethod,
    CallStaticFloatMethodV,
    CallStaticFloatMethodA,
    CallStaticDoubleMethod,
    CallStaticDoubleMethodV,
    CallStaticDoubleMethodA,
    CallStaticVoidMethod,
    CallStaticVoidMethodV,
    CallStaticVoidMethodA,

    GetStaticFieldID,

    GetStaticObjectField,
    GetStaticBooleanField,
    GetStaticByteField,
    GetStaticCharField,
    GetStaticShortField,
    GetStaticIntField,
    GetStaticLongField,
    GetStaticFloatField,
    GetStaticDoubleField,

    SetStaticObjectField,
    SetStaticBooleanField,
    SetStaticByteField,
    SetStaticCharField,
    SetStaticShortField,
    SetStaticIntField,
    SetStaticLongField,
    SetStaticFloatField,
    SetStaticDoubleField,

    NewString,

    GetStringLength,
    GetStringChars,
    ReleaseStringChars,

    NewStringUTF,
    GetStringUTFLength,
    GetStringUTFChars,
    ReleaseStringUTFChars,

    GetArrayLength,

    NewObjectArray,
    GetObjectArrayElement,
    SetObjectArrayElement,

    NewBooleanArray,
    NewByteArray,
    NewCharArray,
    NewShortArray,
    NewIntArray,
    NewLongArray,
    NewFloatArray,
    NewDoubleArray,

    GetBooleanArrayElements,
    GetByteArrayElements,
    GetCharArrayElements,
    GetShortArrayElements,
    GetIntArrayElements,
    GetLongArrayElements,
    GetFloatArrayElements,
    GetDoubleArrayElements,

    ReleaseBooleanArrayElements,
    ReleaseByteArrayElements,
    ReleaseCharArrayElements,
    ReleaseShortArrayElements,
    ReleaseIntArrayElements,
    ReleaseLongArrayElements,
    ReleaseFloatArrayElements,
    ReleaseDoubleArrayElements,

    GetBooleanArrayRegion,
    GetByteArrayRegion,
    GetCharArrayRegion,
    GetShortArrayRegion,
    GetIntArrayRegion,
    GetLongArrayRegion,
    GetFloatArrayRegion,
    GetDoubleArrayRegion,
    SetBooleanArrayRegion,
    SetByteArrayRegion,
    SetCharArrayRegion,
    SetShortArrayRegion,
    SetIntArrayRegion,
    SetLongArrayRegion,
    SetFloatArrayRegion,
    SetDoubleArrayRegion,

    RegisterNatives,
    UnregisterNatives,

    MonitorEnter,
    MonitorExit,

    GetJavaVM,

    GetStringRegion,
    GetStringUTFRegion,

    GetPrimitiveArrayCritical,
    ReleasePrimitiveArrayCritical,

    GetStringCritical,
    ReleaseStringCritical,

    NewWeakGlobalRef,
    DeleteWeakGlobalRef,

    ExceptionCheck,

    NewDirectByteBuffer,
    GetDirectBufferAddress,
    GetDirectBufferCapacity,

    GetObjectRefType
  };

版本資訊

jint GetVersion(JNIEnv *env);

返回本機方法介面的版本。

連鎖:

JNIEnv介面函式表中的索引4。

引數:

env :JNI介面指標。

返回值:

返回高16位的主版本號和低16位的次版本號。

在JDK / JRE 1.1中, GetVersion()返回0x00010001 。

在JDK / JRE 1.2中, GetVersion()返回0x00010002 。

在JDK / JRE 1.4中, GetVersion()返回0x00010004 。

在JDK / JRE 1.6中, GetVersion()返回0x00010006 。

常量

自JDKE / JRE 1.2起:

#define JNI_VERSION_1_1 0x00010001
#define JNI_VERSION_1_2 0x00010002

/* Error codes */
#define JNI_EDETACHED    (-2)              /* thread detached from the VM */
#define JNI_EVERSION     (-3)              /* JNI version error 

自JDKE / JRE 1.4起:

 #define JNI_VERSION_1_4 0x00010004

自JDKE / JRE 1.6起:

 #define JNI_VERSION_1_6 0x00010006

類操作

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

從原始類資料的緩衝區載入一個類。 在DefineClass呼叫返回後,VM不會引用包含原始類資料的緩衝區,如果需要,可以將其丟棄。

連鎖:

JNIEnv介面函式表中的索引5。

引數:

env :JNI介面指標。

name :要定義的類或介面的名稱。 該字串以修改後的UTF-8編碼。

loader :分配給已定義類的類載入器。

buf :包含.class檔案資料的緩衝區。

bufLen :緩衝區長度。

返回值:

如果發生錯誤,則返回Java類物件或NULL 。

丟擲:

ClassFormatError :如果類資料未指定有效類。

ClassCircularityError :如果類或介面是它自己的超類或超介面。

OutOfMemoryError :如果系統記憶體不足。

SecurityException :如果呼叫者嘗試在“java”包樹中定義一個類。

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

在JDK 1.1版中,此函式載入本地定義的類。 它搜尋CLASSPATH環境變數指定的目錄和zip檔案,以查詢具有指定名稱的類。

從Java 2 SDK 1.2版開始,Java安全模型允許非系統類載入和呼叫本機方法。 FindClass定位與當前本機方法關聯的類載入器; 也就是說,宣告本機方法的類的類載入器。 如果本機方法屬於系統類,則不涉及類載入器。 否則,將呼叫適當的類載入器來載入和連結命名類。

從Java 2 SDK 1.2版開始,當通過呼叫介面呼叫FindClass時,沒有當前的本機方法或其關聯的類載入器。 在這種情況下,使用ClassLoader.getSystemClassLoader的結果。 這是虛擬機器為應用程式建立的類載入器,並且能夠定位java.class.path屬性中列出的類。

name引數是完全限定的類名或陣列型別簽名。 例如, java.lang.String類的完全限定類名是:

 "java/lang/String"

陣列類java.lang.Object[]的陣列型別簽名是:

"[Ljava/lang/Object;"

連鎖:

JNIEnv介面函式表中的索引6。

引數:

env :JNI介面指標。

name :完全限定的類名(即包名,由“ / ”分隔,後跟類名)。 如果名稱以“ [ ”(陣列簽名字元)開頭,則返回陣列類。 該字串以修改後的UTF-8編碼。

返回值:

從完全限定名稱返回類物件,如果找不到類,則返回NULL 。

丟擲:

ClassFormatError :如果類資料未指定有效類。

ClassCircularityError :如果類或介面是它自己的超類或超介面。

NoClassDefFoundError :如果找不到所請求的類或介面的定義。

OutOfMemoryError :如果系統記憶體不足。

jclass GetSuperclass(JNIEnv *env, jclass clazz);

如果clazz表示除Object類之外的任何類,則此函式返回表示clazz指定的類的超類的clazz 。

如果clazz指定類Object ,或者clazz表示介面,則此函式返回NULL 。

連鎖:

JNIEnv介面函式表中的索引10。

引數:

env :JNI介面指標。

clazz :一個Java類物件。

返回值:

返回clazz表示的類的超類,或NULL 。

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

確定clazz1的物件是否可以安全地轉換為clazz2 。

連鎖:

JNIEnv介面函式表中的索引11。

引數:

env :JNI介面指標。

clazz1 :第一類引數。

clazz2 :第二類引數。

返回值:

如果滿足以下任一條件,則返回JNI_TRUE :

  • 第一個和第二個類引數引用相同的Java類。
  • 第一個類是第二個類的子類。
  • 第一個類將第二個類作為其介面之一。

異常

拋異常

jint Throw(JNIEnv *env, jthrowable obj);

導致丟擲java.lang.Throwable物件。

連鎖:

JNIEnv介面函式表中的索引13。

引數:

env :JNI介面指標。

obj :一個java.lang.Throwable物件。

返回值:

成功時返回0; 失敗的負​​值。

丟擲:

java.lang.Throwable object obj .

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

使用message指定的message從指定的類構造一個異常物件,並導致丟擲該異常。

連鎖:

JNIEnv介面函式表中的索引14。

引數:

env :JNI介面指標。

clazz : clazz的子類。

message :用於構造java.lang.Throwable物件的訊息。 該字串以修改後的UTF-8編碼。

返回值:

成功時返回0; 失敗的負​​值。

丟擲:

新構造的java.lang.Throwable物件。

jthrowable ExceptionOccurred(JNIEnv *env);

確定是否丟擲異常。 在本機程式碼呼叫ExceptionClear()或Java程式碼處理異常之前,異常會一直丟擲。

連鎖:

JNIEnv介面函式表中的索引15。

引數:

env :JNI介面指標。

返回值:

返回當前正在丟擲的異常物件,如果當前沒有丟擲異常,則返回NULL 。

void ExceptionDescribe(JNIEnv *env);

將堆疊的異常和回溯列印到系統錯誤報告通道,例如stderr 。 這是為除錯提供的便利例程。

連鎖:

JNIEnv介面函式表中的索引16。

引數:

env :JNI介面指標。

void ExceptionClear(JNIEnv *env);

清除當前正在丟擲的任何異常。 如果當前沒有丟擲異常,則此例程無效。

連鎖:

JNIEnv介面函式表中的索引17。

引數:

env :JNI介面指標。

致命錯誤

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

引發致命錯誤,並且不希望VM恢復。 此功能不返回。

連鎖:

JNIEnv介面函式表中的索引18。

引數:

env :JNI介面指標。

msg :錯誤訊息。 該字串以修改後的UTF-8編碼。

我們引入了一個便捷函式來檢查掛起的異常,而不建立對異常物件的本地引用。

jboolean ExceptionCheck(JNIEnv *env);

存在掛起異常時返回JNI_TRUE ; 否則,返回JNI_FALSE 。

連鎖:

JNIEnv介面函式表中的索引228。

以來:

JDK / JRE 1.2

全球參考

jobject NewGlobalRef(JNIEnv *env, jobject obj);

建立對obj引數引用的物件的新全域性引用。 obj引數可以是全域性或本地引用。 必須通過呼叫DeleteGlobalRef()顯式處理全域性引用。

連鎖:

JNIEnv介面函式表中的索引21。

引數:

env :JNI介面指標。

obj :全域性或本地引用。

返回值:

返回全域性引用,如果系統記憶體不足,則返回NULL 。

void DeleteGlobalRef(JNIEnv *env, jobject globalRef);

刪除globalRef指向的全域性引用。

連鎖:

JNIEnv介面函式表中的索引22。

引數:

env :JNI介面指標。

globalRef :全域性參考。

本地參考

本地引用在本機方法呼叫的持續時間內有效。 它們在本機方法返回後自動釋放。 每個本地引用都會花費一定量的Java虛擬機器資源。 程式設計師需要確保本機方法不會過度分配本地引用。 儘管在本機方法返回到Java之後會自動釋放本地引用,但過度分配本地引用可能會導致VM在執行本機方法期間耗盡記憶體。

void DeleteLocalRef(JNIEnv *env, jobject localRef);

刪除localRef指向的本地引用。

連鎖:

JNIEnv介面函式表中的索引23。

引數:

env :JNI介面指標。

localRef :本地引用。

注意 :JDK / JRE 1.1提供了上面的DeleteLocalRef函式,以便程式設計師可以手動刪除本地引用。 例如,如果本機程式碼遍歷可能很大的物件陣列並在每次迭代中使用一個元素,那麼在建立新的本地引用之前刪除對不再使用的陣列元素的本地引用是一個好習慣。下一次迭代。

從JDK / JRE 1.2開始,為本地參考生命週期管理提供了一組額外的功能。 它們是下面列出的四個功能。

jint EnsureLocalCapacity(JNIEnv *env, jint capacity);

確保在當前執行緒中至少可以建立給定數量的本地引用。 成功時返回0; 否則返回一個負數並丟擲一個OutOfMemoryError 。

在進入本機方法之前,VM會自動確保至少可以建立16個本地引用。

為了向後相容,VM分配超出確保容量的本地引用。 (作為除錯支援,VM可能會向用戶發出警告,指出正在建立太多本地引用。在JDK中,程式設計師可以提供-verbose:jni命令列選項來開啟這些訊息。)VM呼叫FatalError if除了確保的容量之外,不能再建立本地引用。

連鎖:

JNIEnv介面函式表中的索引26。

以來:

JDK / JRE 1.2

jint PushLocalFrame(JNIEnv *env, jint capacity);

建立一個新的本地參考框架,其中至少可以建立給定數量的本地參考。 成功時返回0,失敗時返回負數和掛起的OutOfMemoryError 。

請注意,已在先前本地幀中建立的本地引用在當前本地幀中仍然有效。

連鎖:

JNIEnv介面函式表中的索引19。

以來:

JDK / JRE 1.2

jobject PopLocalFrame(JNIEnv *env, jobject result);

彈出當前本地引用框架,釋放所有本地引用,並在給定result物件的先前本地引用框架中返回本地引用。

如果您不需要返回對前一幀的引用,則將NULL作為result傳遞。

連鎖:

JNIEnv介面函式表中的索引20。

以來:

JDK / JRE 1.2

jobject NewLocalRef(JNIEnv *env, jobject ref);

建立一個引用與ref相同的物件的新本地引用。 給定的ref可以是全域性或本地引用。 如果ref引用null則返回NULL 。

連鎖:

JNIEnv介面函式表中的索引25。

以來:

JDK / JRE 1.2

弱全球參考

弱全域性引用是一種特殊的全域性引用。 與普通的全域性引用不同,弱全域性引用允許對底層Java物件進行垃圾回收。 在使用全域性或本地引用的任何情況下都可以使用弱全域性引用。 當垃圾收集器執行時,如果該物件僅由弱引用引用,則它釋放底層物件。 指向釋放物件的弱全域性引用在功能上等效於NULL 。 程式設計師可以通過使用IsSameObject將弱引用與NULL進行比較來檢測弱全域性引用是否指向釋放的物件。

JNI中的弱全域性引用是Java Weak References的簡化版本,可作為Java 2 Platform API( java.lang.ref包及其類)的一部分提供。

澄清 (2001年6月增加)

由於在本機方法執行時可能會發生垃圾收集,因此可以隨時釋放由弱全域性引用引用的物件。 雖然可以在使用全域性引用的地方使用弱全域性引用,但這樣做通常是不合適的,因為它們可能在功能上等同於 NULL 而不另行通知。

雖然 IsSameObject 可用於確定弱全域性引用是否引用已釋放的物件,但它不會阻止此物件立即被釋放。 因此,程式設計師可能不依賴此檢查來確定 在將來的任何JNI函式呼叫中 是否可以使用弱全域性引用(作為非 NULL 引用)。

為了克服這種固有的限制,建議使用JNI函式 NewLocalRef  NewGlobalRef 獲取對同一物件的標準(強)本地或全域性引用 ,並使用此強引用來訪問目標物件。 如果物件已被釋放, 這些函式將返回 NULL ,否則將返回強引用(這將阻止物件被釋放)。 當不再需要立即訪問物件時,應該顯式刪除新引用,從而允許釋放該物件。

弱全域性引用弱於其他型別的弱引用(SoftReference或WeakReference類的Java物件)。 在引用 同一特定物件的SoftReference或WeakReference物件清除其引用之前 ,對特定物件的弱全域性引用在功能上不會等效於 NULL 

弱全域性引用弱於Java對需要完成的物件的內部引用。 在完成引用物件的終結器(如果存在)之後, 弱全域性引用將不會在功能上等效於 NULL 

弱全域性引用和PhantomReferences之間的互動未定義。 特別地,Java VM的實現可以(或可以不)在PhantomReferences之後處理弱全域性引用,並且它可以(或可以不)使用弱全域性引用來保持也由PhantomReference物件引用的物件。 應避免使用弱全域性引用的未定義。

jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);

建立一個新的弱全域性引用。 如果obj引用null ,或者VM記憶體不足,則返回NULL 。 如果VM記憶體不足,將丟擲OutOfMemoryError 。

連鎖:

JNIEnv介面函式表中的索引226。

以來:

JDK / JRE 1.2

void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);

刪除給定的弱全域性引用所需的VM資源。

連鎖:

JNIEnv介面函式表中的索引227。

以來:

JDK / JRE 1.2

物件操作

jobject AllocObject(JNIEnv *env, jclass clazz);

在不呼叫物件的任何建構函式的情況下分配新的Java物件。 返回物件的引用。

clazz引數不能引用陣列類。

連鎖:

JNIEnv介面函式表中的索引27。

引數:

env :JNI介面指標。

clazz :一個Java類物件。

返回值:

返回Java物件,如果無法構造物件,則返回NULL 。

丟擲:

InstantiationException :如果類是介面或抽象類。

OutOfMemoryError :如果系統記憶體不足。

jobject NewObject(JNIEnv *env, jclass clazz, 
jmethodID methodID, ...);

jobject NewObjectA(JNIEnv *env, jclass clazz, 
jmethodID methodID, const jvalue *args);

jobject NewObjectV(JNIEnv *env, jclass clazz, 
jmethodID methodID, va_list args);

構造一個新的Java物件。 方法ID指示要呼叫的構造方法。 必須通過呼叫GetMethodID()並使用<init>作為方法名稱並將void ( V )作為返回型別來獲取此ID。

clazz引數不能引用陣列類。

NewObject的

程式設計師將所有要傳遞給建構函式的引數緊跟在methodID引數之後。 NewObject()接受這些引數並將它們傳遞給程式設計師希望呼叫的Java方法。

連鎖:

JNIEnv介面函式表中的索引28。

NewObjectA

程式設計師將所有要傳遞給建構函式的args jvalues緊跟在methodID引數之後的jvaluesargs陣列中。 NewObjectA()接受此陣列中的引數,然後將它們傳遞給程式設計師希望呼叫的Java方法。

連鎖:

JNIEnv介面函式表中的索引30。

NewObjectV的

程式設計師將所有要傳遞給建構函式的args放在緊跟在methodID引數之後的型別為va_listargs引數中。 NewObjectV()接受這些引數,然後將它們傳遞給程式設計師希望呼叫的Java方法。

連鎖:

JNIEnv介面函式表中的索引29。

引數:

env :JNI介面指標。

clazz :一個Java類物件。

methodID :建構函式的方法ID。

NewObject的附加引數:

建構函式的引數。

NewObjectA的附加引數:

args :建構函式的引數陣列。

NewObjectV的附加引數:

args :建構函式的引數的va_list。

返回值:

返回Java物件,如果無法構造物件,則返回NULL 。

丟擲:

InstantiationException :如果類是介面或抽象類。

OutOfMemoryError :如果系統記憶體不足。

建構函式丟擲的任何異常。

jclass GetObjectClass(JNIEnv *env, jobject obj);

返回物件的類。

連鎖:

JNIEnv介面函式表中的索引31。

引數:

env :JNI介面指標。

obj :一個Java物件(不能為NULL )。

返回值:

返回Java類物件。

jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);

返回obj引數引用的物件的型別。 引數obj可以是本地,全域性或弱全域性引用。

連鎖:

JNIEnv介面函式表中的索引232。

引數:

env :JNI介面指標。

obj :本地,全球或弱全球參考。 

vm :將從中檢索介面的虛擬機器例項。 

env :指向當前執行緒的JNI介面指標所在位置的指標。 

version :請求的JNI版本。

返回值:

函式GetObjectRefType返回以下定義為jobjectRefType列舉值jobjectRefType :

JNIInvalidRefType = 0, 
JNILocalRefType = 1, 
JNIGlobalRefType = 2, 
JNIWeakGlobalRefType = 3

如果引數obj是弱全域性引用型別,則返回將為JNIWeakGlobalRefType 。

如果引數obj是全域性引用型別,則返回值將為JNIGlobalRefType 。

如果引數obj是本地引用型別,則返回將為JNILocalRefType 。

如果obj引數不是有效引用,則此函式的返回值將為JNIInvalidRefType 。

無效引用是不是有效控制代碼的引用。 也就是說, obj指標地址不指向已從Ref建立函式之一分配或從JNI函式返回的儲存器中的位置。

因此, NULL將是無效引用, GetObjectRefType(env,NULL)將返回JNIInvalidRefType 。

另一方面,null引用(指向null的引用)將返回最初建立null引用的引用型別。

GetObjectRefType不能用於已刪除的引用。

由於引用通常實現為指向記憶體資料結構的指標,這些記憶體資料結構可能被VM中的任何引用分配服務重用,因此一旦刪除,就不會指定GetObjectRefType將返回什麼值。

以來:

JDK / JRE 1.6

jboolean IsInstanceOf(JNIEnv *env, jobject obj, 
jclass clazz);

測試物件是否是類的例項。

連鎖:

JNIEnv介面函式表中的索引32。

引數:

env :JNI介面指標。

obj :一個Java物件。

clazz :一個Java類物件。

返回值:

如果obj可以轉換為clazz ,則返回JNI_TRUE ; 否則,返回JNI_FALSE 。 可以將NULL物件強制轉換為任何類。

jboolean IsSameObject(JNIEnv *env, jobject ref1, 
jobject ref2);

測試兩個引用是否引用相同的Java物件。

連鎖:

JNIEnv介面函式表中的索引24。

引數:

env :JNI介面指標。

ref1 :一個Java物件。

ref2 :一個Java物件。

返回值:

如果ref1ref2引用相同的Java物件,則返回JNI_TRUE ,或者都是NULL ; 否則,返回JNI_FALSE 。

jfieldID GetFieldID(JNIEnv *env, jclass clazz, 
const char *name, const char *sig);

返回類的例項(非靜態)欄位的欄位ID。 該欄位由其名稱和簽名指定。 訪問者函式的Get <type> FieldSet <type>欄位系列使用欄位ID來檢索物件欄位。

GetFieldID()導致初始化未初始化的類。

GetFieldID()不能用於獲取陣列的長度欄位。 請改用GetArrayLength() 。

連鎖:

JNIEnv介面函式表中的索引94。

引數:

env :JNI介面指標。

clazz :一個Java類物件。

name :以0結尾的修改後的UTF-8字串中的欄位名稱。

sig :0終止修改的UTF-8字串中的欄位簽名。

返回值:

返回欄位ID,如果操作失敗,則返回NULL 。

丟擲:

NoSuchFieldError :如果找不到指定的欄位。

ExceptionInInitializerError :如果類初始化程式因異常而失敗。

OutOfMemoryError :如果系統記憶體不足。

NativeType 獲取<type>欄位 (JNIEnv *env, jobject obj, 
jfieldID fieldID);
 (JNIEnv *env, jobject obj, 
jfieldID fieldID);

此係列的訪問器例程返回物件的例項(非靜態)欄位的值。 要訪問的欄位由通過呼叫GetFieldID()獲得的欄位ID指定。

下表描述了Get <type> Field例程名稱和結果型別。 您應該使用欄位的Java型別替換Get <type> Field中的type,或者使用表中的一個實際例程名稱,並將NativeType替換為該例程的相應本機型別。

獲取<type>欄位系列的訪問程式例程
獲取<type>欄位例程名稱 原生型別
GetObjectField() jobject
GetBooleanField() jboolean
GetByteField() jbyte
GetCharField() jchar
GetShortField() jshort
GetIntField() jint
GetLongField() jlong
GetFloatField() jfloat
GetDoubleField() jdouble

連鎖:

JNIEnv介面函式表中的索引:

獲取<type>欄位系列的訪問程式例程
獲取<type>欄位例程名稱 指數
GetObjectField() 95
GetBooleanField() 96
GetByteField() 97
GetCharField() 98
GetShortField() 99
GetIntField() 100
GetLongField() 101
GetFloatField() 102
GetDoubleField() 103

引數:

env :JNI介面指標。

obj :一個Java物件(不能為NULL )。

fieldID :有效的欄位ID。

返回值:

返回欄位的內容。

void Set<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID,
NativeType value);

此係列的訪問器例程設定物件的例項(非靜態)欄位的值。 要訪問的欄位由通過呼叫GetFieldID()獲得的欄位ID指定。

下表描述了Set <type> Field例程名稱和值型別。 您應該將Set <type> Field中的type替換 欄位的Java型別,或者使用表中的一個實際例程名稱,並將NativeType替換為該例程的相應本機型別。

設定<type>欄位系列的訪問程式例程
設定<type> Field Routine 原生型別
SetObjectField() jobject
etBooleanField() jboolean
SetByteField() jbyte
SetCharField() jchar
SetShortField() jshort
SetIntField() jint
SetLongField() jlong
SetFloatField() jfloat
SetDoubleField() jdouble

連鎖:

JNIEnv介面函式表中的索引。

設定<type>欄位系列的訪問程式例程
設定<type> Field Routine 指數
SetObjectField() 104
etBooleanField() 105
SetByteField() 106
SetCharField() 107
SetShortField() 108
SetIntField() 109
SetLongField() 110
SetFloatField() 111
SetDoubleField() 112

引數:

env :JNI介面指標。

obj :一個Java物件(不能為NULL )。

fieldID :有效的欄位ID。

value :欄位的新值。

jmethodID GetMethodID(JNIEnv *env, jclass clazz, 
const char *name, const char *sig);

返回類或介面的例項(非靜態)方法的方法ID。 該方法可以在clazz的一個超類中定義,並由clazz繼承。 該方法由其名稱和簽名確定。

GetMethodID()導致初始化未初始化的類。

要獲取建構函式的方法ID,請提供<init>作為方法名稱,並將void ( V )作為返回型別。

連鎖:

JNIEnv介面函式表中的索引33。

引數:

env :JNI介面指標。

clazz :一個Java類物件。

name :以0結尾的修改後的UTF-8字串中的方法名稱。

sig :0終止修改的UTF-8字串中的方法簽名。

返回值:

返回方法ID,如果找不到指定的方法,則返回NULL 。

丟擲:

NoSuchMethodError :如果找不到指定的方法。

ExceptionInInitializerError :如果類初始化程式因異常而失敗。

OutOfMemoryError :如果系統記憶體不足。

NativeType Call<type>Method(JNIEnv *env, jobject obj,
jmethodID methodID, ...);

NativeType Call<type>MethodA(JNIEnv *env, jobject obj,
jmethodID methodID, const jvalue *args);

NativeType Call<type>MethodV(JNIEnv *env, jobject obj,
jmethodID methodID, va_list args);

來自這三個操作系列的方法用於從本機方法呼叫Java例項方法。它們只是將引數傳遞給它們呼叫的方法的機制不同。

這些操作系列根據指定的方法ID在Java物件上呼叫例項(非靜態)方法。 必須通過呼叫GetMethodID ()獲取methodID引數。

當這些函式用於呼叫私有方法和建構函式時,方法ID必須從obj的真實類派生,而不是從其超類之一派生。

Call<type>Method 方法例程

程式設計