相关链接:JNI函数(上)
对象操作
AllocObject
jobject AllocObject(JNIEnv *env, jclass clazz);
不调用构造函数的情况下,分配一个新的对象。返回对象引用。
注意:java语言规范,12.6.1 实现finalize:“在对象o
上调用了Object
的构造方法,且构造方法调用成功,否则对象o
不可终结”。因为AllocObject()
未调用构造方法,所以通过此函数创建的对象不符合终结机制(finalization),不会被终结。
clazz
参数不可为数组class。
函数表27
参数
clazz:Java class对象引用。不可为空。
返回值
返回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对象。methodID表示要调用的构造方法。ID必须通过调用GetMethodID()
获得,方法名传 <init>
,方法签名为void(V)
。
clazz
参数不可为数组class。
NewObject
程序员将所有参数直接跟在methodID
参数后面传入。 NewObject()
接受这些参数并将它们传入程序员想调用的Java方法中去。
函数表28
NewObjectA
程序员直接将构造方法需要的参数放在名为args
的jvalues
数组中,跟在methodID
后面传入。NewObjectA()
接受这个数组作为参数,并将他们传入要调用的Java方法中。
函数表30
NewObjectV
传入va_list
类型的构造函数参数args。
GetObjectClass
jclass GetObjectClass(JNIEnv *env, jobject obj);
返回对象的class。
函数表31
obj
: java对象, 不可为NULL
。
GetObjectRefType
jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);
返回obj对象的引用类型。obj参数可为局部引用,全局引用,全局弱引用,或null。
函数表232
参数
obj:局部引用,全局引用或全局弱引用。
返回值
此函数返回以下jobjectRefType
的枚举值:
JNIInvalidRefType = 0//obj是无效的引用 JNILocalRefType = 1//obj是局部引用 JNIGlobalRefType = 2//obj是全局引用 JNIWeakGlobalRefType = 3//如果obj是全局弱引用
无效引用是一个无效句柄的引用。即obj指针地址未指向一个通过Ref创建函数之一分配的内存或JNI返回的内存地址。
因此,NULL
是一个无效引用, GetObjectRefType(env,NULL)
将返回JNIInvalidRefType
。
换句话说,null引用是一个指向null的引用,将返回最开始创建为null的引用。
GetObjectRefType
不能用在已删除的引用上。
由于引用通常被实现为指向能潜在地被任何VM引用分配服务重用的内存数据结构,一旦删除,GetObjectRefType的返回值就不是指定的了。
IsInstanceOf
jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz);
测试一个对象是否是某个class的实例。
函数表32
参数
obj:Java对象,可能为空。
clazz:Java class对象,不可为空。
返回值
如果obj可以被强转为clazz,则返回JNI_TRUE
,否则返回JNI_FALSE
。NULL
对象可强转为任何类。
IsSameObject
jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2);
测试两个引用是否指向同一个Java对象。
函数表24
ref1,ref2皆可为null。
如果ref1,ref2指向同一个Java对象或者二者皆为null,则返回JNI_TRUE;否则返回JNI_FALSE。
访问对象域
GetFieldID
jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
函数表94
返回类的实例域(非静态域)ID,该字段由其名称和签名指定。Get<type>Field
和Set<type>Field
的访问器函数族使用ID来获取对象成员。
GetFieldID()
导致未被初始化的类被初始化。GetFieldID()
不能用来获取数组的长度字段,如需获取数组长度,使用GetArrayLength()
函数。
参数
clazz:Java class对象,不可为空。
name:字段名称(0-结束符 MUTF-8字符串),不可为空。
sig:字段签名(0-结束符 MUTF-8字符串),不可为空。
返回值
成功则返回字段ID,如果操作失败,则返回NULL。
异常
NoSuchFieldError:如果指定字段找不到。
ExceptionInInitializerError:由于异常导致类初始化失败。
OutOfMemoryError:系统内存不足。
Get<type>Field例程
NativeType Get<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID);
此程序族返回对象实例域的值,要访问的字段的ID通过GetFieldID()
方法获取。
下表描述了Get<type>Field
例程的名称和返回值,用字段的Java类型替换Get<type>Field
中的type
,或者用下表中的名称,并且用替换NativeType
为相应例程的native type。
Get | Native类型 |
---|---|
GetObjectField() | jobject |
GetBooleanField() | jboolean |
GetByteField() | jbyte |
GetCharField() | jchar |
GetShortField() | jshort |
GetIntField() | jint |
GetLongField() | jlong |
GetFloatField() | jfloat |
GetDoubleField() | jdouble |
链接
Get<type>Field程序族各自对应的JNI接口函数表索引:
Get | 索引 |
---|---|
GetObjectField() | 95 |
GetBooleanField() | 96 |
GetByteField() | 97 |
GetCharField() | 98 |
GetShortField() | 99 |
GetIntField() | 100 |
GetLongField() | 101 |
GetFloatField() | 102 |
GetDoubleField() | 103 |
Set<type>Field 例程
void Set<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID, NativeType value);
此访问器家族修改对象的实例域,通过调用GetFieldID()
获得访问指定字段的字段id。
下表展示了Set<type>Field例程的名称和类型,使用它们时应该将type替换字段的java类型,或者使用表中的实际例程名称,并替换NativeType为相应的native类型。
Set | Native类型 |
---|---|
SetObjectField() | jobject |
SetBooleanField() | jboolean |
SetByteField() | jbyte |
SetCharField() | jchar |
SetShortField() | jshort |
SetIntField() | jint |
SetLongField() | jlong |
SetFloatField() | jfloat |
SetDoubleField() | jdouble |
链接
Set | Index |
---|---|
SetObjectField() | 104 |
SetBooleanField() | 105 |
SetByteField() | 106 |
SetCharField() | 107 |
SetShortField() | 108 |
SetIntField() | 109 |
SetLongField() | 110 |
SetFloatField() | 111 |
SetDoubleField() | 112 |
调用静态方法
GetStaticMethodID
jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig);
根据方法名称和签名,返回静态方法id。GetStaticMethodID()
将引发未初始化的类初始化。
函数表113
参数
clazz:class对象,不可为空
name:静态方法名称,不可为空
sig:方法签名,不可为空
返回值
成功,返回方法id;失败,返回NULL。
异常
NoSuchMethodError:指定的静态方法未找到
ExceptionInInitializerError:类初始化异常
OutOfMemoryError:内存不足
CallStatic<type>Method,CallStatic<type>MethodA,CallStatic<type>MethodV例程
NativeType CallStatic<type>Method(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例程
将所有参数跟在methodID
后面,CallStatic<type>Method例程接受可变参数,然后将他们传入期望调用的java方法。
CallStatic<type>MethodA 例程
将参数放在一个jvalues类型的args数组中,跟在methodID参数后面。CallStaticMethodA例程接受将参数至于数组中,然后将他们传入期望调用的java方法中。
CallStatic<type>MethodV例程
将参数至于va_list中,CallStaticMethodV接受这些参数,然后将他们传入期望调用的java方法中。
下表根据result类型描述每一个方法调用,你应该用方法的java类型替换CallStatic<type>Method中的type,或者表中实际的方法调用例程名称,并替换NativeType为例程对应的native类型。
CallStatic | Native类型 |
---|---|
CallStaticVoidMethod() CallStaticVoidMethodA() CallStaticVoidMethodV() | void |
CallStaticObjectMethod() CallStaticObjectMethodA() CallStaticObjectMethodV() | jobject |
CallStaticBooleanMethod() CallStaticBooleanMethodA() CallStaticBooleanMethodV() | jboolean |
CallStaticByteMethod() CallStaticByteMethodA() CallStaticByteMethodV() | jbyte |
CallStaticCharMethod() CallStaticCharMethodA() CallStaticCharMethodV() | jchar |
CallStaticShortMethod() CallStaticShortMethodA() CallStaticShortMethodV() | jshort |
CallStaticIntMethod() CallStaticIntMethodA() CallStaticIntMethodV() | jint |
CallStaticLongMethod() CallStaticLongMethodA() CallStaticLongMethodV() | jlong |
CallStaticFloatMethod() CallStaticFloatMethodA() CallStaticFloatMethodV() | jfloat |
CallStaticDoubleMethod() CallStaticDoubleMethodA() CallStaticDoubleMethodV() | jdouble |
链接
CallStatic | 函数索引 |
---|---|
CallStaticVoidMethod() CallStaticVoidMethodA() CallStaticVoidMethodV() | 141 143 142 |
CallStaticObjectMethod() CallStaticObjectMethodA() CallStaticObjectMethodV() | 114 116 115 |
CallStaticBooleanMethod() CallStaticBooleanMethodA() CallStaticBooleanMethodV() | 117 119 118 |
CallStaticByteMethod() CallStaticByteMethodA() CallStaticByteMethodV() | 120 122 121 |
CallStaticCharMethod() CallStaticCharMethodA() CallStaticCharMethodV() | 123 125 124 |
CallStaticShortMethod() CallStaticShortMethodA() CallStaticShortMethodV() | 126 128 127 |
CallStaticIntMethod() CallStaticIntMethodA() CallStaticIntMethodV() | 129 131 130 |
CallStaticLongMethod() CallStaticLongMethodA() CallStaticLongMethodV() | 132 134 133 |
CallStaticFloatMethod() CallStaticFloatMethodA() CallStaticFloatMethodV() | 135 137 136 |
CallStaticDoubleMethod() CallStaticDoubleMethodA() CallStaticDoubleMethodV() | 138 140 139 |
参数
methodID
:有效的静态方法id
CallStatic<type>Method例程可选参数:该静态方法的参数
CallStatic<type>MethodA例程可选参数:args
:一组参数
CallStatic<type>MethodV例程可选参数:args
:va_list参数
返回值
调用的静态方法的返回值。
异常
java方法执行期间引发的异常。
String操作
此规范不假设JVM内部如何表示字符串。下列操作返回Strings:
- GetStringChars()
- GetStringUTFChars()
- GetStringRegion()
- GetStringUTFRegion()
- GetStringCritical()
因此不强制null中断。程序员应通过GetStringLength()
或 GetStringUTFLength()
确定缓冲容量大小。
NewString
jstring NewString(JNIEnv *env, const jchar *unicodeChars, jsize len);
由Unicode字符构造新的 java.lang.String
对象。
参数
unicodeChars :指向Unicode字符串。可为空,为空时len
必须为0。
len:Unicode字符串长度。可为0。
返回值
Java String对象,如果字符串无法被构造,返回null。
异常
OutOfMemoryError :系统内存不足时。
GetStringLength
jsize GetStringLength(JNIEnv *env, jstring string);
返回Java String的长度(Unicode字符的数量)。
GetStringChars
const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy);
返回指向String的Unicode字符数组的指针。此指针在ReleaseStringChars()
调用之前始终有效。如果isCopy
字段不为空,则 *isCopy
设置为 JNI_TRUE