本章作为JNI函数的参考部分。 它提供了所有JNI功能的完整列表。 它还提供了JNI函数表的确切布局。
请注意使用术语“必须”来描述对JNI程序员的限制。 例如,当您看到某个JNI函数必须接收非NULL对象时,您有责任确保不将NULL传递给该JNI函数。 因此,JNI实现不需要在该JNI函数中执行NULL指针检查。
本章的一部分改编自Netscape的JRI文档。
参考材料按其用法分组。 参考部分由以下功能区域组成:
目录
NewObject,NewObjectA,NewObjectV
调用 Method Routines,Call MethodA Routines,Call MethodV Routines
CallNonvirtual Method Routines,CallNonvirtual MethodA Routines,CallNonvirtual MethodV Routines
CallStatic Method Routines,CallStatic MethodA Routines,CallStatic MethodV Routines
GetStringCritical,ReleaseStringCritical
GetPrimitiveArrayCritical,ReleasePrimitiveArrayCritical
接口功能表
可以通过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
};
版本信息
GetVersion
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
类操作
defineClass
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”包树中定义一个类。
findClass
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
:如果系统内存不足。
getSuperclass
jclass GetSuperclass(JNIEnv *env, jclass clazz);
如果clazz
表示除Object
类之外的任何类,则此函数返回表示clazz
指定的类的超类的clazz
。
如果clazz
指定类Object
,或者clazz
表示接口,则此函数返回NULL
。
连锁:
JNIEnv接口函数表中的索引10。
参数:
env
:JNI接口指针。
clazz
:一个Java类对象。
返回值:
返回clazz
表示的类的超类,或NULL
。
IsAssignableFrom
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
.
ThrowNew
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
对象。
ExceptionOccurred
jthrowable ExceptionOccurred(JNIEnv *env);
确定是否抛出异常。 在本机代码调用ExceptionClear()
或Java代码处理异常之前,异常会一直抛出。
连锁:
JNIEnv接口函数表中的索引15。
参数:
env
:JNI接口指针。
返回值:
返回当前正在抛出的异常对象,如果当前没有抛出异常,则返回NULL
。
ExceptionDescribe
void ExceptionDescribe(JNIEnv *env);
将堆栈的异常和回溯打印到系统错误报告通道,例如stderr
。 这是为调试提供的便利例程。
连锁:
JNIEnv接口函数表中的索引16。
参数:
env
:JNI接口指针。
ExceptionClear
void ExceptionClear(JNIEnv *env);
清除当前正在抛出的任何异常。 如果当前没有抛出异常,则此例程无效。
连锁:
JNIEnv接口函数表中的索引17。
参数:
env
:JNI接口指针。
致命错误
void FatalError(JNIEnv *env, const char *msg);
引发致命错误,并且不希望VM恢复。 此功能不返回。
连锁:
JNIEnv接口函数表中的索引18。
参数:
env
:JNI接口指针。
msg
:错误消息。 该字符串以修改后的UTF-8编码。
ExceptionCheck
我们引入了一个便捷函数来检查挂起的异常,而不创建对异常对象的本地引用。
jboolean ExceptionCheck(JNIEnv *env);
存在挂起异常时返回JNI_TRUE
; 否则,返回JNI_FALSE
。
连锁:
JNIEnv接口函数表中的索引228。
以来:
JDK / JRE 1.2
全球和本地参考
全球参考
NewGlobalRef
jobject NewGlobalRef(JNIEnv *env, jobject obj);
创建对obj
参数引用的对象的新全局引用。 obj
参数可以是全局或本地引用。 必须通过调用DeleteGlobalRef()
显式处理全局引用。
连锁:
JNIEnv接口函数表中的索引21。
参数:
env
:JNI接口指针。
obj
:全局或本地引用。
返回值:
返回全局引用,如果系统内存不足,则返回NULL
。
DeleteGlobalRef
void DeleteGlobalRef(JNIEnv *env, jobject globalRef);
删除globalRef
指向的全局引用。
连锁:
JNIEnv接口函数表中的索引22。
参数:
env
:JNI接口指针。
globalRef
:全局参考。
本地参考
本地引用在本机方法调用的持续时间内有效。 它们在本机方法返回后自动释放。 每个本地引用都会花费一定量的Java虚拟机资源。 程序员需要确保本机方法不会过度分配本地引用。 尽管在本机方法返回到Java之后会自动释放本地引用,但过度分配本地引用可能会导致VM在执行本机方法期间耗尽内存。
DeleteLocalRef
void DeleteLocalRef(JNIEnv *env, jobject localRef);
删除localRef
指向的本地引用。
连锁:
JNIEnv接口函数表中的索引23。
参数:
env
:JNI接口指针。
localRef
:本地引用。
注意 :JDK / JRE 1.1提供了上面的DeleteLocalRef
函数,以便程序员可以手动删除本地引用。 例如,如果本机代码遍历可能很大的对象数组并在每次迭代中使用一个元素,那么在创建新的本地引用之前删除对不再使用的数组元素的本地引用是一个好习惯。下一次迭代。
从JDK / JRE 1.2开始,为本地参考生命周期管理提供了一组额外的功能。 它们是下面列出的四个功能。
EnsureLocalCapacity
jint EnsureLocalCapacity(JNIEnv *env, jint capacity);
确保在当前线程中至少可以创建给定数量的本地引用。 成功时返回0; 否则返回一个负数并抛出一个OutOfMemoryError
。
在进入本机方法之前,VM会自动确保至少可以创建16个本地引用。
为了向后兼容,VM分配超出确保容量的本地引用。 (作为调试支持,VM可能会向用户发出警告,指出正在创建太多本地引用。在JDK中,程序员可以提供-verbose:jni
命令行选项来打开这些消息。)VM调用FatalError
if除了确保的容量之外,不能再创建本地引用。
连锁:
JNIEnv接口函数表中的索引26。
以来:
JDK / JRE 1.2
PushLocalFrame
jint PushLocalFrame(JNIEnv *env, jint capacity);
创建一个新的本地参考框架,其中至少可以创建给定数量的本地参考。 成功时返回0,失败时返回负数和挂起的OutOfMemoryError
。
请注意,已在先前本地帧中创建的本地引用在当前本地帧中仍然有效。
连锁:
JNIEnv接口函数表中的索引19。
以来:
JDK / JRE 1.2
PopLocalFrame
jobject PopLocalFrame(JNIEnv *env, jobject result);
弹出当前本地引用框架,释放所有本地引用,并在给定result
对象的先前本地引用框架中返回本地引用。
如果您不需要返回对前一帧的引用,则将NULL
作为result
传递。
连锁:
JNIEnv接口函数表中的索引20。
以来:
JDK / JRE 1.2
NewLocalRef
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对象引用的对象。 应避免使用弱全局引用的未定义。
NewWeakGlobalRef
jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);
创建一个新的弱全局引用。 如果obj
引用null
,或者VM内存不足,则返回NULL
。 如果VM内存不足,将抛出OutOfMemoryError
。
连锁:
JNIEnv接口函数表中的索引226。
以来:
JDK / JRE 1.2
DeleteWeakGlobalRef
void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);
删除给定的弱全局引用所需的VM资源。
连锁:
JNIEnv接口函数表中的索引227。
以来:
对象操作
AllocObject
jobject AllocObject(JNIEnv *env, jclass clazz);
在不调用对象的任何构造函数的情况下分配新的Java对象。 返回对象的引用。
clazz参数不能引用数组类。
连锁:
JNIEnv接口函数表中的索引27。
参数:
env
:JNI接口指针。
clazz
:一个Java类对象。
返回值:
返回Java对象,如果无法构造对象,则返回NULL
。
抛出:
InstantiationException
:如果类是接口或抽象类。
OutOfMemoryError
:如果系统内存不足。
NewObject,NewObjectA,NewObjectV
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
参数之后的jvalues
的args
数组中。 NewObjectA()
接受此数组中的参数,然后将它们传递给程序员希望调用的Java方法。
连锁:
JNIEnv接口函数表中的索引30。
NewObjectV的
程序员将所有要传递给构造函数的args
放在紧跟在methodID
参数之后的类型为va_list
的args
参数中。 NewObjectV()
接受这些参数,然后将它们传递给程序员希望调用的Java方法。
连锁:
JNIEnv接口函数表中的索引29。
参数:
env
:JNI接口指针。
clazz
:一个Java类对象。
methodID
:构造函数的方法ID。
NewObject的附加参数:
构造函数的参数。
NewObjectA的附加参数:
args
:构造函数的参数数组。
NewObjectV的附加参数:
args
:构造函数的参数的va_list。
返回值:
返回Java对象,如果无法构造对象,则返回NULL
。
抛出:
InstantiationException
:如果类是接口或抽象类。
OutOfMemoryError
:如果系统内存不足。
构造函数抛出的任何异常。
GetObjectClass
jclass GetObjectClass(JNIEnv *env, jobject obj);
返回对象的类。
连锁:
JNIEnv接口函数表中的索引31。
参数:
env
:JNI接口指针。
obj
:一个Java对象(不能为NULL
)。
返回值:
返回Java类对象。
GetObjectRefType
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
IsInstanceOf
jboolean IsInstanceOf(JNIEnv *env, jobject obj,
jclass clazz);
测试对象是否是类的实例。
连锁:
JNIEnv接口函数表中的索引32。
参数:
env
:JNI接口指针。
obj
:一个Java对象。
clazz
:一个Java类对象。
返回值:
如果obj
可以转换为clazz
,则返回JNI_TRUE
; 否则,返回JNI_FALSE
。 可以将NULL
对象强制转换为任何类。
IsSameObject
jboolean IsSameObject(JNIEnv *env, jobject ref1,
jobject ref2);
测试两个引用是否引用相同的Java对象。
连锁:
JNIEnv接口函数表中的索引24。
参数:
env
:JNI接口指针。
ref1
:一个Java对象。
ref2
:一个Java对象。
返回值:
如果ref1
和ref2
引用相同的Java对象,则返回JNI_TRUE
,或者都是NULL
; 否则,返回JNI_FALSE
。
访问对象的字段
GetFieldID
jfieldID GetFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);
返回类的实例(非静态)字段的字段ID。 该字段由其名称和签名指定。 访问者函数的Get <type> Field和Set <type>字段系列使用字段ID来检索对象字段。
GetFieldID()
导致初始化未初始化的类。
GetFieldID()
不能用于获取数组的长度字段。 请改用GetArrayLength()
。
连锁:
JNIEnv接口函数表中的索引94。
参数:
env
:JNI接口指针。
clazz
:一个Java类对象。
name
:以0结尾的修改后的UTF-8字符串中的字段名称。
sig
:0终止修改的UTF-8字符串中的字段签名。
返回值:
返回字段ID,如果操作失败,则返回NULL
。
抛出:
NoSuchFieldError
:如果找不到指定的字段。
ExceptionInInitializerError
:如果类初始化程序因异常而失败。
OutOfMemoryError
:如果系统内存不足。
Get<type> Field Routines
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>字段例程名称 | 原生类型 |
---|---|
GetObjectField() |
jobject |
GetBooleanField() |
jboolean |
GetByteField() |
jbyte |
GetCharField() |
jchar |
GetShortField() |
jshort |
GetIntField() |
jint |
GetLongField() |
jlong |
GetFloatField() |
jfloat |
GetDoubleField() |
jdouble |
连锁:
JNIEnv接口函数表中的索引:
获取<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。
返回值:
返回字段的内容。
Set<type> Field Routines
void
Set<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID,
NativeType value);
此系列的访问器例程设置对象的实例(非静态)字段的值。 要访问的字段由通过调用GetFieldID()
获得的字段ID指定。
下表描述了Set <type> Field例程名称和值类型。 您应该将Set <type> Field中的type替换为 字段的Java类型,或者使用表中的一个实际例程名称,并将NativeType替换为该例程的相应本机类型。
设置<type> Field Routine | 原生类型 |
---|---|
SetObjectField() |
jobject |
S etBooleanField() |
jboolean |
SetByteField() |
jbyte |
SetCharField() |
jchar |
SetShortField() |
jshort |
SetIntField() |
jint |
SetLongField() |
jlong |
SetFloatField() |
jfloat |
SetDoubleField() |
jdouble |
连锁:
JNIEnv接口函数表中的索引。
设置<type> Field Routine | 指数 |
---|---|
SetObjectField() |
104 |
S etBooleanField() |
105 |
SetByteField() |
106 |
SetCharField() |
107 |
SetShortField() |
108 |
SetIntField() |
109 |
SetLongField() |
110 |
SetFloatField() |
111 |
SetDoubleField() |
112 |
参数:
env
:JNI接口指针。
obj
:一个Java对象(不能为NULL
)。
fieldID
:有效的字段ID。
value
:字段的新值。
调用实例方法
的GetMethodID
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
:如果系统内存不足。
Call<type>Method Routines, Call<type>MethodA Routines, Call<type>MethodV Routines
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 方法例程
程序员将所有要传递给方法的参数紧跟在methodID
参数之后。 Call <type> Method例程接受这些参数并将它们传递给程序员希望调用的Java方法。
Call<type>Method MethodA Routines
程序员将方法的所有参数jvalues
紧跟在methodID
参数之后的jvalues
的args
数组中。 Call <type> MethodA例程接受此数组中的参数,然后将它们传递给程序员希望调用的Java方法。
Call<type> MethodV Routines
程序员将方法的所有参数放在紧跟在methodID
参数之后的类型为va_list
的args
参数中。 Call <type> MethodV例程接受参数,然后将它们传递给程序员希望调用的Java方法。
下表根据结果类型描述了每个方法调用例程。 您应该将Call <type> Method中的type替换为您正在调用的方法的Java类型(或使用表中实际的方法调用例程名称之一),并将NativeType替换为该例程的相应本机类型。
调用<type>方法例程名称 | 原生类型 |
---|---|
CallVoidMethod() CallVoidMethodA() CallVoidMethodV() |
空虚 |
CallObjectMethod() CallObjectMethodA() CallObjectMethodV() |
jobject |
CallBooleanMethod() CallBooleanMethodA() CallBooleanMethodV() |
jboolean |
CallByteMethod() CallByteMethodA() CallByteMethodV() |
jbyte |
CallCharMethod() CallCharMethodA() CallCharMethodV() |
jchar |
CallShortMethod() CallShortMethodA() CallShortMethodV() |
jshort |
CallIntMethod() CallIntMethodA() CallIntMethodV() |
jint |
CallLongMethod() CallLongMethodA() CallLongMethodV() |
jlong |
CallFloatMethod() CallFloatMethodA() CallFloatMethodV() |
jfloat |
CallDoubleMethod() CallDoubleMethodA() CallDoubleMethodV() |
jdouble |
连锁:
JNIEnv接口函数表中的索引:
调用<type>方法例程名称 | 指数 |
---|---|
CallVoidMethod() CallVoidMethodA() CallVoidMethodV() |
61 |
CallObjectMethod() CallObjectMethodA() CallObjectMethodV() |
34 |
CallBooleanMethod() CallBooleanMethodA() CallBooleanMethodV() |
37 |
CallByteMethod() CallByteMethodA() CallByteMethodV() |
40 |
CallCharMethod() CallCharMethodA() CallCharMethodV() |
43 |
CallShortMethod() CallShortMethodA() CallShortMethodV() |
46 |
CallIntMethod() CallIntMethodA() CallIntMethodV() |
49 |
CallLongMethod() CallLongMethodA() CallLongMethodV() |
52 |
CallFloatMethod() CallFloatMethodA() CallFloatMethodV() |
55 |
CallDoubleMethod() CallDoubleMethodA() CallDoubleMethodV() |
58 |
参数:
env
:JNI接口指针。
obj
:一个Java对象。
methodID
:方法ID。
Call <type>方法例程的附加参数:
Java方法的参数。
Call <type> MethodA例程的附加参数:
args
:一组参数。
Call <type> MethodV例程的附加参数:
args
:一个参数的va_list。
返回值:
返回调用Java方法的结果。
抛出:
Exceptions raised during the execution of the Java method.
CallNonvirtual <type> Method Routines,CallNonvirtual <type> MethodA Routines,CallNonvirtual <type> MethodV Routines
NativeType CallNonvirtual <type>Method (JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, ...);
NativeType CallNonvirtual <type> MethodA (JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, const jvalue *args);
NativeType CallNonvirtual <type> MethodV (JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, va_list args);
这些操作系列根据指定的类和方法ID在Java对象上调用实例(非静态)方法。该methodID
参数必须通过调用获得GetMethodID
()
的类clazz
。
所述CallNonvirtual <类型>方法例程的家庭和呼叫<类型>方法例程的家庭是不同的。调用<type>方法例程根据对象的类调用方法,而CallNonvirtual <type> Method例程根据clazz
参数指定的类调用方法,从中获取方法ID。方法ID必须从对象的真实类或其超类之一获得。
CallNonvirtual <type> Method Routines
程序员将所有要传递给参数的参数放在参数后面methodID
。所述CallNonvirtual <类型>方法例程接受这些参数并将其传给编程人员所要调用的Java方法。
CallNonvirtual <type> MethodA例程
程序员将方法的所有参数放在紧跟在参数后面的args
数组中。所述CallNonvirtual <类型>方法a routine接受这些参数这个阵列中,并且,反过来,其传给编程人员所要调用的Java方法。jvalues
methodID
CallNonvirtual <type> MethodV Routines
程序员将方法的所有参数放在紧跟在参数args
后面的类型va_list
的methodID
参数中。该CallNonvirtualMethodV routine接受这些参数,并且,反过来,它们传给编程人员所要调用的Java方法。
下表根据结果类型描述了每个方法调用例程。此时应更换型在CallNonvirtual <类型>方法的Java类型的方法,或者使用的实际方法从表中调用例程的名字之一,并取代本地类型与对应的原生类型,常规。
CallNonvirtual <type> Method Routine Name | 原生类型 |
---|---|
CallNonvirtualVoidMethod() CallNonvirtualVoidMethodA() CallNonvirtualVoidMethodV() |
空虚 |
CallNonvirtualObjectMethod() CallNonvirtualObjectMethodA() CallNonvirtualObjectMethodV() |
jobject |
CallNonvirtualBooleanMethod() CallNonvirtualBooleanMethodA() CallNonvirtualBooleanMethodV() |
jboolean |
CallNonvirtualByteMethod() CallNonvirtualByteMethodA() CallNonvirtualByteMethodV() |
jbyte |
CallNonvirtualCharMethod() CallNonvirtualCharMethodA() CallNonvirtualCharMethodV() |
jchar |
CallNonvirtualShortMethod() CallNonvirtualShortMethodA() CallNonvirtualShortMethodV() |
jshort |
CallNonvirtualIntMethod() CallNonvirtualIntMethodA() CallNonvirtualIntMethodV() |
jint |
CallNonvirtualLongMethod() CallNonvirtualLongMethodA() CallNonvirtualLongMethodV() |
jlong |
CallNonvirtualFloatMethod() CallNonvirtualFloatMethodA() CallNonvirtualFloatMethodV() |
jfloat |
CallNonvirtualDoubleMethod() CallNonvirtualDoubleMethodA() CallNonvirtualDoubleMethodV() |
jdouble |
连锁:
JNIEnv接口函数表中的索引。
CallNonvirtual <type> Method Routine Name | 指数 |
---|---|
CallNonvirtualVoidMethod() CallNonvirtualVoidMethodA() CallNonvirtualVoidMethodV() |
91 93 92 |
CallNonvirtualObjectMethod() CallNonvirtualObjectMethodA() CallNonvirtualObjectMethodV() |
64 66 65 |
CallNonvirtualBooleanMethod() CallNonvirtualBooleanMethodA() CallNonvirtualBooleanMethodV() |
67 69 68 |
CallNonvirtualByteMethod() CallNonvirtualByteMethodA() CallNonvirtualByteMethodV() |
70 72 71 |
CallNonvirtualCharMethod() CallNonvirtualCharMethodA() CallNonvirtualCharMethodV() |
73 75 74 |
CallNonvirtualShortMethod() CallNonvirtualShortMethodA() CallNonvirtualShortMethodV() |
76 78 77 |
CallNonvirtualIntMethod() CallNonvirtualIntMethodA() CallNonvirtualIntMethodV() |
79 81 80 |
CallNonvirtualLongMethod() CallNonvirtualLongMethodA() CallNonvirtualLongMethodV() |
82 84 83 |
CallNonvirtualFloatMethod() CallNonvirtualFloatMethodA() CallNonvirtualFloatMethodV() |
85 87 86 |
CallNonvirtualDoubleMethod() CallNonvirtualDoubleMethodA() CallNonvirtualDoubleMethodV() |
88 90 89 |
参数:
env
:JNI接口指针。
clazz:
a
Java类。
obj
:一个Java对象。
methodID
:方法ID。
CallNonvirtual <type>方法例程的附加参数:
Java方法的参数。
CallNonvirtual <type> MethodA例程的附加参数:
args
:一组参数。
CallNonvirtual <type> MethodV例程的附加参数:
args
:一个va_list
论点。
返回值:
返回调用Java方法的结果。
抛出:
执行Java方法期间引发的异常。
访问静态字段
GetStaticFieldID
jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);
返回类的静态字段的字段ID。该字段由其名称和签名指定。所述GetStatic <类型>字段和SetStatic <类型>字段的存取器函数系列使用域ID来检索静态字段。
GetStaticFieldID()
导致未初始化的类被初始化。
连锁:
JNIEnv接口函数表中的索引144。
参数:
env
:JNI接口指针。
clazz
:Java类对象。
name
:0终止修改的UTF-8字符串中的静态字段名称。
sig
:0终止修改的UTF-8字符串中的字段签名。
返回值:
返回字段ID,或者NULL
如果找不到指定的静态字段。
抛出:
NoSuchFieldError
:如果找不到指定的静态字段。
ExceptionInInitializerError
:如果类初始值设定项因异常而失败。
OutOfMemoryError
:如果系统内存不足。
GetStatic <type> Field Routines
NativeType GetStatic <type> Field (JNIEnv *env, jclass clazz,
jfieldID fieldID);
这个访问器例程系列返回对象的静态字段的值。要访问的字段由字段ID指定,该字段ID是通过调用获得的GetStaticFieldID()
。
下表描述了get例程名称和结果类型的系列。此时应更换型在GetStatic <类型>字段的Java类型的字段,或者从表中的实际静态字段访问例程名,并替换本地类型与对应的原生类型,常规。
GetStatic <type>字段例程名称 | 原生类型 |
---|---|
GetStaticObjectField () |
jobject |
GetStaticBooleanField () |
jboolean |
GetStaticByteField () |
jbyte |
GetStaticCharField () |
jchar |
GetStaticShortField () |
jshort |
GetStaticIntField () |
jint |
GetStaticLongField () |
jlong |
GetStaticFloatField () |
jfloat |
GetStaticDoubleField () |
jdouble |
连锁:
JNIEnv接口函数表中的索引。
GetStatic <type>字段例程名称 | 指数 |
---|---|
GetStaticObjectField () |
145 |
GetStaticBooleanField () |
146 |
GetStaticByteField () |
147 |
GetStaticCharField () |
148 |
GetStaticShortField () |
149 |
GetStaticIntField () |
150 |
GetStaticLongField () |
151 |
GetStaticFloatField () |
152 |
GetStaticDoubleField () |
153 |
参数:
env
:JNI接口指针。
clazz
:Java类对象。
fieldID
:静态字段ID。
返回值:
返回静态字段的内容。
GetStatic <type> Field Routines
NativeType GetStatic <type> Field (JNIEnv *env, jclass clazz,
jfieldID fieldID);
这个访问器例程系列返回对象的静态字段的值。要访问的字段由字段ID指定,该字段ID是通过调用获得的GetStaticFieldID()
。
下表描述了get例程名称和结果类型的系列。此时应更换型在GetStatic <类型>字段的Java类型的字段,或者从表中的实际静态字段访问例程名,并替换本地类型与对应的原生类型,常规。
GetStatic <type>字段例程名称 | 原生类型 |
---|---|
GetStaticObjectField () |
jobject |
GetStaticBooleanField () |
jboolean |
GetStaticByteField () |
jbyte |
GetStaticCharField () |
jchar |
GetStaticShortField () |
jshort |
GetStaticIntField () |
jint |
GetStaticLongField () |
jlong |
GetStaticFloatField () |
jfloat |
GetStaticDoubleField () |
jdouble |
连锁:
JNIEnv接口函数表中的索引。
GetStatic <type>字段例程名称 | 指数 |
---|---|
GetStaticObjectField () |
145 |
GetStaticBooleanField () |
146 |
GetStaticByteField () |
147 |
GetStaticCharField () |
148 |
GetStaticShortField () |
149 |
GetStaticIntField () |
150 |
GetStaticLongField () |
151 |
GetStaticFloatField () |
152 |
GetStaticDoubleField () |
153 |
参数:
env
:JNI接口指针。
clazz
:Java类对象。
fieldID
:静态字段ID。
返回值:
返回静态字段的内容。
SetStatic <type> Field Routines
void
SetStatic <type> Field NativeType(JNIEnv *env, jclass clazz,
jfieldID fieldID,value);
这个访问器例程系列设置对象的静态字段的值。要访问的字段由字段ID指定,该字段ID是通过调用获得的GetStaticFieldID()
。
下表描述了set例程名称和值类型。此时应更换型在SetStatic <类型>字段的Java类型的字段,或从表中实际设置静态字段例程名,并替换本地类型与对应的原生类型,常规。
SetStatic <type>字段例程名称 | 本地类型 |
---|---|
SetStaticObjectField () |
jobject |
SetStaticBooleanField () |
jboolean |
SetStaticByteField () |
jbyte |
SetStaticCharField () |
jchar |
SetStaticShortField () |
jshort |
SetStaticIntField () |
jint |
SetStaticLongField () |
jlong |
SetStaticFloatField () |
jfloat |
SetStaticDoubleField () |
jdouble |
连锁:
JNIEnv接口函数表中的索引。
SetStatic <type>字段例程名称 | 指数 |
---|---|
SetStaticObjectField () |
154 |
SetStaticBooleanField () |
155 |
SetStaticByteField () |
156 |
SetStaticCharField () |
157 |
SetStaticShortField () |
158 |
SetStaticIntField () |
159 |
SetStaticLongField () |
160 |
SetStaticFloatField () |
161 |
SetStaticDoubleField () |
162 |
参数:
env
:JNI接口指针。
clazz
:Java类对象。
fieldID
:静态字段ID。
value
:该领域的新价值。
调用静态方法
GetStaticMethodID
jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);
返回类的静态方法的方法ID。该方法由其名称和签名指定。
GetStaticMethodID()
导致未初始化的类被初始化。
连锁:
JNIEnv接口函数表中的索引113。
参数:
env
:JNI接口指针。
clazz
:Java类对象。
name
:0终止的修改的UTF-8字符串中的静态方法名称。
sig
:0终止修改的UTF-8字符串中的方法签名。
返回值:
返回方法ID,或者NULL
操作失败。
抛出:
NoSuchMethodError
:如果找不到指定的静态方法。
ExceptionInInitializerError
:如果类初始值设定项因异常而失败。
OutOfMemoryError
:如果系统内存不足。
CallStatic <type> Method Routines,CallStatic <type> MethodA Routines,CallStatic <type> MethodV Routines
NativeType CallStatic <type>方法 (JNIEnv *env, jclass clazz,
jmethodID methodID, ...);
NativeType CallStatic <type> MethodA (JNIEnv *env, jclass clazz,
jmethodID methodID, jvalue *args);
NativeType CallStatic <type> MethodV (JNIEnv *env, jclass clazz,
jmethodID methodID, va_list args);
此系列操作根据指定的方法ID在Java对象上调用静态方法。该methodID
参数必须通过调用来获得GetStaticMethodID
()
。
方法ID必须来自clazz
,而不是来自其超类之一。
CallStatic <type> Method Routines
程序员应该在参数后面立即放置要传递给方法的所有methodID
参数。所述CallStatic <类型>方法例程接受这些参数并将其传给编程人员所要调用的Java方法。
CallStatic <type> MethodA Routines
程序员应该将方法的所有参数放在紧跟在参数后面的args
数组中。所述CallStaticMethodA例程接受此阵列中的参数,并且,反过来,其传给编程人员所要调用的Java方法。jvalues
methodID
CallStatic <type> MethodV例程
程序员应该将方法的所有参数放在紧跟在参数args
后面的类型va_list
的methodID
参数中。该CallStaticMethodV routine接受这些参数,并且,反过来,它们传给编程人员所要调用的Java方法。
下表根据结果类型描述了每个方法调用例程。此时应更换型在CallStatic <类型>方法的Java类型的方法,或实际方法从表中调用例程的名字之一,并取代本地类型与对应的原生类型,常规。
CallStatic <type> Method Routine Name | 原生类型 |
---|---|
CallStaticVoidMethod () CallStaticVoidMethodA () CallStaticVoidMethod V() |
空虚 |
CallStaticObjectMethod () CallStaticObjectMethod A() CallStaticObjectMethod V() |
jobject |
CallStaticBooleanMethod () CallStaticBooleanMethod A() CallStaticBooleanMethod V() |
jboolean |
CallStaticByteMethod () CallStaticByteMethod A() CallStaticByteMethod V() |
jbyte |
CallStaticCharMethod () CallStaticCharMethod A() CallStaticCharMethod V() |
jchar |
CallStaticShortMethod () CallStaticShortMethod A() CallStaticShortMethod V() |
jshort |
CallStaticIntMethod () CallStaticIntMethod A() CallStaticIntMethod V() |
jint |
CallStaticLongMethod () CallStaticLongMethod A() CallStaticLongMethod V() |
jlong |
CallStaticFloatMethod () CallStaticFloatMethod A() CallStaticFloatMethod V() |
jfloat |
CallStaticDoubleMethod () CallStaticDoubleMethod A() CallStaticDoubleMethod V() |
jdouble |
连锁:
JNIEnv接口函数表中的索引。
CallStatic <type> Method Routine Name | 指数 |
---|---|
CallStaticVoidMethod () CallStaticVoidMethodA () CallStaticVoidMethod V() |
141 143 142 |
CallStaticObjectMethod () CallStaticObjectMethod A() CallStaticObjectMethod V() |
114 116 115 |
CallStaticBooleanMethod () CallStaticBooleanMethod A() CallStaticBooleanMethod V() |
117 119 118 |
CallStaticByteMethod () CallStaticByteMethod A() CallStaticByteMethod V() |
120 122 121 |
CallStaticCharMethod () CallStaticCharMethod A() CallStaticCharMethod V() |
123 125 124 |
CallStaticShortMethod () CallStaticShortMethod A() CallStaticShortMethod V() |
126 128 127 |
CallStaticIntMethod () CallStaticIntMethod A() CallStaticIntMethod V() |
129 131 130 |
CallStaticLongMethod () CallStaticLongMethod A() CallStaticLongMethod V() |
132 134 133 |
CallStaticFloatMethod () CallStaticFloatMethod A() CallStaticFloatMethod V() |
135 137 136 |
CallStaticDoubleMethod () CallStaticDoubleMethod A() CallStaticDoubleMethod V() |
138 140 139 |
参数:
env
:JNI接口指针。
clazz
:Java类对象。
methodID
:静态方法ID。
CallStatic <type>方法例程的附加参数:
静态方法的参数。
CallStatic <type> MethodA例程的附加参数:
args
:一组参数。
CallStatic <type> MethodV例程的附加参数:
args
:一个va_list
论点。
返回值:
返回调用静态Java方法的结果。
抛出:
Exceptions raised during the execution of the Java method.
字符串操作
NewString
jstring NewString(JNIEnv *env, const jchar *unicodeChars,
jsize len);
java.lang.String
从Unicode字符数组构造一个新对象。
连锁:
JNIEnv接口函数表中的索引163。
参数:
env
:JNI接口指针。
unicodeChars
:指向Unicode字符串的指针。
len
:Unicode字符串的长度。
返回值:
返回Java字符串对象,或者NULL
无法构造字符串。
抛出:
OutOfMemoryError
:如果系统内存不足。
GetStringLength
jsize GetStringLength(JNIEnv *env, jstring string);
返回Java字符串的长度(Unicode字符数)。
连锁:
JNIEnv接口函数表中的索引164。
参数:
env
:JNI接口指针。
string
:Java字符串对象。
返回值:
返回Java字符串的长度。
GetStringChars
const jchar * GetStringChars(JNIEnv *env, jstring string,
jboolean *isCopy);
返回指向字符串的Unicode字符数组的指针。该指针在ReleaseStringChars()
被调用之前有效。
如果isCopy
不是NULL
,则*isCopy
设置为JNI_TRUE
复制; 或者JNI_FALSE
如果没有复制则设置为。
连锁:
JNIEnv接口函数表中的索引165。
参数:
env
:JNI接口指针。
string
:Java字符串对象。
isCopy
:指向布尔值的指针。
返回值:
返回指向Unicode字符串的指针,或者NULL
操作是否失败。
ReleaseStringChars
void ReleaseStringChars(JNIEnv *env, jstring string,
const jchar *chars);
通知VM本机代码不再需要访问权限chars
。该chars
参数是从所获得的指针string
使用GetStringChars()
。
连锁:
JNIEnv接口函数表中的索引166。
参数:
env
:JNI接口指针。
string
:Java字符串对象。
chars
:指向Unicode字符串的指针。
NewStringUTF
jstring NewStringUTF(JNIEnv *env, const char *bytes);
使用java.lang.String
修改后的UTF-8编码从字符数组构造一个新对象。
连锁:
JNIEnv接口函数表中的索引167。
参数:
env
:JNI接口指针。
bytes
:指向修改后的UTF-8字符串的指针。
返回值:
返回Java字符串对象,或者NULL
无法构造字符串。
抛出:
OutOfMemoryError
:如果系统内存不足。
GetStringUTFLength
jsize GetStringUTFLength(JNIEnv *env, jstring string);
返回字符串的修改后的UTF-8表示的字节长度。
连锁:
JNIEnv接口函数表中的索引168。
参数:
env
:JNI接口指针。
string
:Java字符串对象。
返回值:
返回字符串的UTF-8长度。
GetStringUTFChars
const char * GetStringUTFChars(JNIEnv *env, jstring string,
jboolean *isCopy);
返回指向字节数组的指针,该字节数组表示修改后的UTF-8编码中的字符串。此数组在释放之前有效ReleaseStringUTFChars()
。
如果isCopy
不是NULL
,则*isCopy
设置为JNI_TRUE
复制; 或者JNI_FALSE
如果没有复制则设置为。
连锁:
JNIEnv接口函数表中的索引169。
参数:
env
:JNI接口指针。
string
:Java字符串对象。
isCopy
:指向布尔值的指针。
返回值:
返回指向已修改的UTF-8字符串的指针,或者NULL
操作是否失败。
ReleaseStringUTFChars
void ReleaseStringUTFChars(JNIEnv *env, jstring string,
const char *utf);
通知VM本机代码不再需要访问权限utf
。该utf
参数是从衍生的指针string
使用GetStringUTFChars()
。
连锁:
JNIEnv接口函数表中的索引170。
参数:
env
:JNI接口指针。
string
:Java字符串对象。
utf
:指向修改后的UTF-8字符串的指针。
注意:在JDK / JRE 1.1中,程序员可以在用户提供的缓冲区中获取原始数组元素。从JDK / JRE 1.2开始,提供了一组额外的功能,允许本机代码在用户提供的缓冲区中获取Unicode(UTF-16)或修改的UTF-8编码的字符。请参阅以下功能。
GetStringRegion
void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);
len
将从偏移量开始的Unicode字符数复制start
到给定缓冲区buf
。
引发StringIndexOutOfBoundsException
索引溢出。
连锁:
JNIEnv接口函数表中的索引220。
以来:
JDK / JRE 1.2
GetStringUTFRegion
< void GetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize len, char *buf);
平移len
偏移量开始的Unicode字符数start
成改性UTF-8编码并将结果置于在给定的缓冲器buf
。
引发StringIndexOutOfBoundsException
索引溢出。
连锁:
JNIEnv接口函数表中的索引221。
以来:
JDK / JRE 1.2
GetStringCritical,ReleaseStringCritical
const jchar * GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy);
void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *carray);
这两个函数的语义类似于现有Get/ReleaseStringChars
函数。如果可能,VM返回指向字符串元素的指针; 否则,制作副本。但是,如何使用这些功能存在重大限制。在由Get/ReleaseStringCritical
调用包含的代码段中,本机代码不得发出任意JNI调用,或导致当前线程阻塞。
限制Get/ReleaseStringCritical
与那些相似Get/ReleasePrimitiveArrayCritical
。
LINKAGE(GetStringCritical):
JNIEnv接口函数表中的索引224。
LINKAGE(ReleaseStingCritical):
JNIEnv接口函数表中的索引225。
以来:
JDK / JRE 1.2
阵列操作
GetArrayLength
jsize GetArrayLength(JNIEnv *env, jarray array);
返回数组中的元素数。
连锁:
JNIEnv接口函数表中的索引171。
参数:
env
:JNI接口指针。
array
:一个Java数组对象。
返回值:
返回数组的长度。
NewObjectArray
jobjectArray NewObjectArray(JNIEnv *env, jsize length,
jclass elementClass, jobject initialElement);
构造一个包含类中对象的新数组elementClass
。所有元素最初都设置为initialElement
。
连锁:
JNIEnv接口函数表中的索引172。
参数:
env
:JNI接口指针。
length
:数组大小。
elementClass
:数组元素类。
initialElement
:初始化值。
返回值:
返回Java数组对象,或者NULL
无法构造数组。
抛出:
OutOfMemoryError
:如果系统内存不足。
GetObjectArrayElement
jobject GetObjectArrayElement(JNIEnv *env,
jobjectArray array, jsize index);
返回Object
数组的元素。
连锁:
JNIEnv接口函数表中的索引173。
参数:
env
:JNI接口指针。
array
:一个Java数组。
index
:数组索引。
返回值:
返回一个Java对象。
抛出:
ArrayIndexOutOfBoundsException
:if如果index
未在数组中指定有效索引。
SetObjectArrayElement
void SetObjectArrayElement(JNIEnv *env, jobjectArray array,
jsize index, jobject value);
设置Object
数组的元素。
连锁:
JNIEnv接口函数表中的索引174。
参数:
env
:JNI接口指针。
array
:一个Java数组。
index
:数组索引。
value
:新的价值。
抛出:
ArrayIndexOutOfBoundsException
:if如果index
未在数组中指定有效索引。
ArrayStoreException
:如果类value
不是数组的元素类的子类。
新的<PrimitiveType>数组例程
ArrayType New <PrimitiveType> Array (JNIEnv *env, jsize length);
用于构造新原始数组对象的一系列操作。下表描述了特定的基本数组构造函数。您应该使用此表中的一个实际原始数组构造函数例程名称替换New <PrimitiveType> Array,并将ArrayType替换为该例程的相应数组类型。
新的<PrimitiveType>数组例程 | 数组类型 |
---|---|
NewBooleanArray() |
jbooleanArray |
NewByteArray() |
jbyteArray |
NewCharArray() |
jcharArray |
NewShortArray() |
jshortArray |
NewIntArray() |
jintArray |
NewLongArray() |
jlongArray |
NewFloatArray() |
jfloatArray |
NewDoubleArray() |
jdoubleArray |
连锁:
JNIEnv接口函数表中的索引。
新的<PrimitiveType>数组例程 | 指数 |
---|---|
NewBooleanArray() |
175 |
NewByteArray() |
176 |
NewCharArray() |
177 |
NewShortArray() |
178 |
NewIntArray() |
179 |
NewLongArray() |
180 |
NewFloatArray() |
181 |
NewDoubleArray() |
182 |
参数:
env
:JNI接口指针。
length
:数组长度。
返回值:
返回Java数组,或者NULL
无法构造数组。
Get<PrimitiveType> ArrayElements例程
NativeType *
获取<PrimitiveType> ArrayElements (JNIEnv *env,
ArrayType
array, jboolean *isCopy);
返回基本数组主体的一系列函数。结果有效,直到调用相应的Release <
PrimitiveType >
ArrayElements()函数。小号因斯返回的数组可能是Java数组的副本,因此对返回数组的更改不必反映在原始 array
直到Release<PrimitiveType>ArrayElements()
被调用。
如果isCopy
不是NULL
,则*isCopy
设置为JNI_TRUE
复制; 或者JNI_FALSE
如果没有复制则设置为。
下表描述了特定的原始数组元素访问器。您应该进行以下替换:
- 将Get <PrimitiveType> ArrayElements替换为下表中的一个实际原始元素访问器例程名称。
- 将ArrayType替换为相应的数组类型。
- 将NativeType替换为该例程的相应本机类型。
无论如何在Java VM中表示布尔数组,GetBooleanArrayElements()
总是返回一个指向的指针jbooleans
,每个字节表示一个元素(解包表示)。其他类型的所有数组都保证在内存中是连续的。
获取<PrimitiveType> ArrayElements例程 | 数组类型 | 原生类型 |
---|---|---|
GetBooleanArrayElements() |
jbooleanArray | jboolean |
GetByteArrayElements() |
jbyteArray | jbyte |
GetCharArrayElements() |
jcharArray | jchar |
GetShortArrayElements() |
jshortArray | jshort |
GetIntArrayElements() |
jintArray | jint |
GetLongArrayElements() |
jlongArray | jlong |
GetFloatArrayElements() |
jfloatArray | jfloat |
GetDoubleArrayElements() |
jdoubleArray | jdouble |
连锁:
JNIEnv接口函数表中的索引。
获取<PrimitiveType> ArrayElements例程 | 指数 |
---|---|
GetBooleanArrayElements() |
183 |
GetByteArrayElements() |
184 |
GetCharArrayElements() |
185 |
GetShortArrayElements() |
186 |
GetIntArrayElements() |
187 |
GetLongArrayElements() |
188 |
GetFloatArrayElements() |
189 |
GetDoubleArrayElements() |
190 |
参数:
env
:JNI接口指针。
array
:Java字符串对象。
isCopy
:指向布尔值的指针。
返回值:
返回指向数组元素的指针,或者NULL
操作是否失败。
发布<PrimitiveType> ArrayElements例程
void
发布<PrimitiveType> ArrayElements NativeType(JNIEnv *env,
ArrayType
array,
*elems, jint mode);
一系列函数,用于通知VM本机代码不再需要访问elems
。该elems
参数是array
使用相应的Get <
PrimitiveType >
ArrayElements()函数派生的指针。如有必要,此功能将复制elems
对原始阵列所做的所有更改。
该mode
参数提供有关如何释放数组缓冲区的信息。mode
如果elems
不是元素的副本,则无效array
。否则,mode
会产生以下影响,如下表所示:
模式 | 行动 |
---|---|
0 |
复制内容并释放elems 缓冲区 |
JNI_COMMIT |
复制内容但不释放elems 缓冲区 |
JNI_ABORT |
释放缓冲区而不复制可能的更改 |
在大多数情况下,程序员将“0”传递给mode
参数,以确保固定和复制数组的一致行为。其他选项使程序员可以更好地控制内存管理,并且应该非常谨慎地使用。
下表描述了构成原始数组处理器系列的特定例程。您应该进行以下替换:
- 将Release <PrimitiveType> ArrayElements替换为下表中的一个实际原始数组处理程序例程名称。
- 将ArrayType替换为相应的数组类型。
- 将NativeType替换为该例程的相应本机类型。
发布<PrimitiveType> ArrayElements例程 | 数组类型 | 原生类型 |
---|---|---|
ReleaseBooleanArrayElements() |
jbooleanArray | jboolean |
ReleaseByteArrayElements() |
jbyteArray | jbyte |
ReleaseCharArrayElements() |
jcharArray | jchar |
ReleaseShortArrayElements() |
jshortArray | jshort |
ReleaseIntArrayElements() |
jintArray | jint |
ReleaseLongArrayElements() |
jlongArray | jlong |
ReleaseFloatArrayElements() |
jfloatArray | jfloat |
ReleaseDoubleArrayElements() |
jdoubleArray | jdouble |
连锁:
JNIEnv接口函数表中的索引。
发布<PrimitiveType> ArrayElements例程 | 指数 |
---|---|
ReleaseBooleanArrayElements() |
191 |
ReleaseByteArrayElements() |
192 |
ReleaseCharArrayElements() |
193 |
ReleaseShortArrayElements() |
194 |
ReleaseIntArrayElements() |
195 |
ReleaseLongArrayElements() |
196 |
ReleaseFloatArrayElements() |
197 |
ReleaseDoubleArrayElements() |
198 |
参数:
env
:JNI接口指针。
array
:一个Java数组对象。
elems
:指向数组元素的指针。
mode
:发布模式。
获取<PrimitiveType> ArrayRegion例程
void 获取<PrimitiveType> ArrayRegion (JNIEnv *env,
ArrayType NativeTypearray,
jsize start, jsize len,*buf);
一系列函数,用于将基本数组的区域复制到缓冲区中。
下表描述了特定的原始数组元素访问器。你应该做以下替换:
- 将Get <PrimitiveType> ArrayRegion替换为下表中的一个实际原始元素访问器例程名称。
- 将ArrayType替换为相应的数组类型。
- 将NativeType替换为该例程的相应本机类型。
获取<PrimitiveType> ArrayRegion例程 | 数组类型 | 原生类型 |
---|---|---|
GetBooleanArrayRegion() |
jbooleanArray | jboolean |
GetByteArrayRegion() |
jbyteArray | jbyte |
GetCharArrayRegion() |
jcharArray | jchar |
GetShortArrayRegion() |
jshortArray | jhort |
GetIntArrayRegion() |
jintArray | jint |
GetLongArrayRegion() |
jlongArray | jlong |
GetFloatArrayRegion() |
jfloatArray | jloat |
GetDoubleArrayRegion() |
jdoubleArray | jdouble |
连锁:
JNIEnv接口函数表中的索引。
获取<PrimitiveType> ArrayRegion系列数组访问器例程
获取<PrimitiveType> ArrayRegion例程 | 指数 |
---|---|
GetBooleanArrayRegion() |
199 |
GetByteArrayRegion() |
200 |
GetCharArrayRegion() |
201 |
GetShortArrayRegion() |
202 |
GetIntArrayRegion() |
203 |
GetLongArrayRegion() |
204 |
GetFloatArrayRegion() |
205 |
GetDoubleArrayRegion() |
206 |
参数:
env
:JNI接口指针。
array
:一个Java数组。
start
:起始指数。
len
:要复制的元素数。
buf
:目标缓冲区。
抛出:
ArrayIndexOutOfBoundsException
:如果该区域中的某个索引无效。
Set<PrimitiveType> ArrayRegion例程
void
Set<PrimitiveType> ArrayRegion (JNIEnv *env,
ArrayType const NativeTypearray,
jsize start, jsize len,*buf);
一系列函数,用于从缓冲区复制基本数组的区域。
下表描述了特定的原始数组元素访问器。您应该进行以下替换:
- 将Set <PrimitiveType> ArrayRegion替换为下表中的一个实际原始元素访问器例程名称。
- 将ArrayType替换为相应的数组类型。
- 将NativeType替换为该例程的相应本机类型。
Set<PrimitiveType> ArrayRegion系列数组访问器例程
设置<PrimitiveType> ArrayRegion Routine | 数组类型 | 原生类型 |
---|---|---|
SetBooleanArrayRegion() |
jbooleanArray | jboolean |
SetByteArrayRegion() |
jbyteArray | jbyte |
SetCharArrayRegion() |
jcharArray | jchar |
SetShortArrayRegion() |
jshortArray | jshort |
SetIntArrayRegion() |
jintArray | jint |
SetLongArrayRegion() |
jlongArray | jlong |
SetFloatArrayRegion() |
jfloatArray | jfloat |
SetDoubleArrayRegion() |
jdoubleArray | jdouble |
连锁:
JNIEnv接口函数表中的索引。
设置<PrimitiveType> ArrayRegion系列数组访问器例程
设置<PrimitiveType> ArrayRegion Routine | 指数 |
---|---|
SetBooleanArrayRegion() |
207 |
SetByteArrayRegion() |
208 |
SetCharArrayRegion() |
209 |
SetShortArrayRegion() |
210 |
SetIntArrayRegion() |
211 |
SetLongArrayRegion() |
212 |
SetFloatArrayRegion() |
213 |
SetDoubleArrayRegion() |
214 |
参数:
env
:JNI接口指针。
array
:一个Java数组。
start
:起始指数。
len
:要复制的元素数。
buf
:源缓冲区。
抛出:
ArrayIndexOutOfBoundsException
:如果该区域中的某个索引无效。
注意:从JDK / JRE 1.1开始,程序员可以使用 从JDK / JRE 1.3开始引入的新功能允许本机代码获取指向数组元素的直接指针,即使VM不支持固定。 |
GetPrimitiveArrayCritical,ReleasePrimitiveArrayCritical
void * GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy);
void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode);
这两个函数的语义与现有Get/Release<primitivetype>ArrayElements
函数非常相似。如果可能,VM返回指向基元数组的指针; 否则,制作副本。但是,如何使用这些功能存在重大限制。
调用之后GetPrimitiveArrayCritical
,本机代码在调用之前不应该运行很长一段时间ReleasePrimitiveArrayCritical
。我们必须将这对函数中的代码视为在“关键区域”中运行。在关键区域内,本机代码不能调用其他JNI函数或任何可能导致当前线程阻塞并等待另一个Java线程的系统调用。(例如,当前线程不能调用read
另一个Java线程正在写入的流。)
这些限制使得本机代码更有可能获得阵列的未复制版本,即使VM不支持固定。例如,当本机代码持有指向通过其获得的数组的指针时,VM可以临时禁用垃圾收集GetPrimitiveArrayCritical
。
多对GetPrimtiveArrayCritical
并且ReleasePrimitiveArrayCritical
可以嵌套。例如:
jint len = (*env)->GetArrayLength(env, arr1);
jbyte *a1 = (*env)->GetPrimitiveArrayCritical(env, arr1, 0);
jbyte *a2 = (*env)->GetPrimitiveArrayCritical(env, arr2, 0);
/* We need to check in case the VM tried to make a copy. */
if (a1 == NULL || a2 == NULL) {
... /* out of memory exception thrown */
}
memcpy(a1, a2, len);
(*env)->ReleasePrimitiveArrayCritical(env, arr2, a2, 0);
(*env)->ReleasePrimitiveArrayCritical(env, arr1, a1, 0);
请注意,GetPrimitiveArrayCritical
如果VM在内部以不同格式表示数组,则可能仍会复制该数组。因此,我们需要针对NULL
可能的内存不足情况检查其返回值。
LINKAGE(GetPrimitiveArrayCritical):
JNIEnv接口函数表中的链接索引222。
LINKAGE(ReleasePrimitiveArrayCritical):
JNIEnv接口函数表中的链接索引223。
以来:
JDK / JRE 1.2
注册本机方法
RegisterNatives
jint RegisterNatives(JNIEnv *env, jclass clazz,
const JNINativeMethod *methods, jint nMethods);
使用clazz
参数指定的类注册本机方法。该methods
参数指定JNINativeMethod
包含本机方法的名称,签名和函数指针的结构数组。JNINativeMethod结构的name
和signature
字段是指向修改后的UTF-8字符串的指针。该nMethods
参数指定数组中的本机方法数。的JNINativeMethod
结构定义如下:
typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;
名义上的函数指针必须具有以下签名:
ReturnType (*fnPtr)(JNIEnv *env, jobject objectOrClass, ...);
连锁:
JNIEnv接口函数表中的索引215。
参数:
env
:JNI接口指针。
clazz
:Java类对象。
methods
:类中的本机方法。
nMethods
:类中的本机方法数。
返回值:
成功时返回“0”; 失败时返回负值。
抛出:
NoSuchMethodError
:如果找不到指定的方法或该方法不是本机方法。
UnregisterNatives
jint UnregisterNatives(JNIEnv *env, jclass clazz);
取消注册类的本机方法。该类返回到它与其本机方法函数链接或注册之前的状态。
此函数不应在普通本机代码中使用。相反,它为特殊程序提供了重新加载和重新链接本机库的方法。
连锁:
JNIEnv接口函数表中的索引216。
参数:
env
:JNI接口指针。
clazz
:Java类对象。
返回值:
成功时返回“0”; 失败时返回负值。
监控操作
MonitorEnter
jint MonitorEnter(JNIEnv *env, jobject obj);
输入与引用的基础Java对象关联的监视器obj
。
输入与obj引用的对象关联的监视器。该obj
参考绝不能NULL
。
每个Java对象都有一个与之关联的监视器。如果当前线程已拥有与之关联的监视器obj
,则会增加监视器中的计数器,指示此线程进入监视器的次数。如果与之关联的监视器obj
不属于任何线程,则当前线程将成为监视器的所有者,将此监视器的条目数设置为1.如果另一个线程已拥有与之关联的监视器obj
,则当前线程将等待,直到监视器为释放,然后再次尝试获得所有权。
通过MonitorEnter
JNI函数调用输入的监视器无法使用monitorexit
Java虚拟机指令或同步方法返回退出。一个MonitorEnter
JNI函数调用和monitorenter
Java虚拟机指令可比赛进入与同一对象相关联的监视器。
为避免死锁,MonitorEnter
必须使用MonitorExit
JNI调用退出通过JNI函数调用输入的监视器,除非该DetachCurrentThread
调用用于隐式释放JNI监视器。
连锁:
JNIEnv接口函数表中的索引217。
参数:
env
:JNI接口指针。
obj
:普通的Java对象或类对象。
返回值:
成功时返回“0”; 失败时返回负值。
MonitorExit
jint MonitorExit(JNIEnv *env, jobject obj);
当前线程必须是与引用的基础Java对象关联的监视器的所有者obj
。线程递减计数器,指示它进入此监视器的次数。如果计数器的值变为零,则当前线程释放监视器。
本机代码不得用于MonitorExit
退出通过synchronized方法或monitorenter
Java虚拟机指令输入的监视器。
连锁:
JNIEnv接口函数表中的索引218。
参数:
env
:JNI接口指针。
obj
:普通的Java对象或类对象。
返回值:
成功时返回“0”; 失败时返回负值。
例外:
IllegalMonitorStateException
:如果当前线程不拥有监视器。
NIO支持
与NIO相关的入口点允许本机代码访问java.nio
直接缓冲区。直接缓冲区的内容可能存在于普通垃圾收集堆之外的本机内存中。有关直接缓冲区的信息,
JDK / JRE 1.4中引入的三个新函数允许JNI代码创建,检查和操作直接缓冲区:
Java虚拟机的每个实现都必须支持这些功能,但并不是每个实现都需要支持对直接缓冲区的JNI访问。如果JVM不支持此类访问,则NewDirectByteBuffer和GetDirectBufferAddress函数必须始终返回NULL,并且GetDirectBufferCapacity函数必须始终返回-1。如果JVM 确实支持此类访问,则必须实现这三个函数以返回适当的值。
NewDirectByteBuffer
jobject NewDirectByteBuffer(JNIEnv * env,void * address,jlong capacity);
分配并返回一个直接java.nio.ByteBuffer中参照所述存储器块起始于存储器地址的地址和延伸能力字节。
调用此函数并将生成的字节缓冲区对象返回到Java级代码的本机代码应确保缓冲区引用可供读取的内存的有效区域,并在适当时写入。尝试从Java代码访问无效的内存位置将返回任意值,没有可见效果,或导致抛出未指定的异常。
连锁:
JNIEnv接口函数表中的索引229。
参数:
env:JNIEnv接口指针
address:内存区域的起始地址(不能为NULL)
capacity:内存区域的大小(以字节为单位)(必须为正)
返回值:
返回对新实例化的java.nio.ByteBuffer对象的本地引用。如果发生异常,或者此虚拟机不支持对直接缓冲区的JNI访问,则返回NULL。
例外:
OutOfMemoryError:如果ByteBuffer对象的分配失败
以来:
JDK / JRE 1.4
GetDirectBufferAddress
void * GetDirectBufferAddress(JNIEnv * env,jobject buf);
获取并返回给定直接java.nio.Buffer引用的内存区域的起始地址。
此函数允许本机代码通过缓冲区对象访问Java代码可访问的相同内存区域。
连锁:
JNIEnv接口函数表中的索引230。
参数:
env:JNIEnv接口指针
buf:直接java.nio.Buffer对象(不能为NULL)
返回值:
返回缓冲区引用的内存区域的起始地址。如果内存区域未定义,如果给定对象不是直接java.nio.Buffer,或者此虚拟机不支持对直接缓冲区的JNI访问,则返回NULL。
以来:
JDK / JRE 1.4
GetDirectBufferCapacity
jlong GetDirectBufferCapacity(JNIEnv * env,jobject buf);
获取并返回给定直接java.nio.Buffer引用的内存区域的容量。容量是内存区域包含的元素数。
连锁:
JNIEnv接口函数表中的索引231。
参数:
env:JNIEnv接口指针
buf:直接java.nio.Buffer对象(不能为NULL)
返回值:
返回与缓冲区关联的内存区域的容量。如果给定对象不是直接java.nio.Buffer,如果对象是未对齐的视图缓冲区且处理器体系结构不支持未对齐访问,或者此虚拟机不支持对直接缓冲区的JNI访问,则返回-1。
以来:
JDK / JRE 1.4
反思支持
如果程序员知道方法或字段的名称和类型,则可以使用JNI调用Java方法或访问Java字段。Java Core Reflection API允许程序员在运行时内省Java类。JNI在JNI中使用的字段和方法ID之间提供了一组转换函数,用于Java Core Reflection API中使用的字段和方法对象。
FromReflectedMethod
jmethodID FromReflectedMethod(JNIEnv *env, jobject method);
将a java.lang.reflect.Method
或java.lang.reflect.Constructor
object转换为方法ID。
连锁:
JNIEnv接口函数表中的索引7。
以来:
JDK / JRE 1.2
FromReflectedField
jfieldID FromReflectedField(JNIEnv *env, jobject field);
将a转换java.lang.reflect.Field
为字段ID。
连锁:
JNIEnv接口函数表中的索引8。
以来:
JDK / JRE 1.2
ToReflectedMethod
jobject ToReflectedMethod(JNIEnv *env, jclass cls,
jmethodID methodID, jboolean isStatic);
衍生自一种方法ID转换cls
到一个java.lang.reflect.Method
或java.lang.reflect.Constructor
对象。如果方法ID引用静态字段,则isStatic
必须设置为JNI_TRUE
,JNI_FALSE
否则。
OutOfMemoryError
如果失败则抛出并返回0。
连锁:
JNIEnv接口函数表中的索引9。
以来:
JDK / JRE 1.2
ToReflectedField
jobject ToReflectedField(JNIEnv *env, jclass cls,
jfieldID fieldID, jboolean isStatic);
将从派生的字段ID转换cls
为java.lang.reflect.Field
对象。isStatic
必须设置为JNI_TRUE
if fieldID
引用静态字段,JNI_FALSE
否则。
OutOfMemoryError
如果失败则抛出并返回0。
连锁:
JNIEnv接口函数表中的索引12。
以来:
JDK / JRE 1.2
Java VM接口
GetJavaVM
jint GetJavaVM(JNIEnv *env, JavaVM **vm);
返回与当前线程关联的Java VM接口(在Invocation API中使用)。结果放在第二个参数指向的位置vm
。
连锁:
JNIEnv接口函数表中的索引219。
参数:
env
:JNI接口指针。
vm
:指向结果放置位置的指针。
返回值:
成功时返回“0”; 失败时返回负值。