- 对象操作函数
- AllocObject
- NewObject, NewObjectA, NewObjectV
- GetObjectClass
- GetObjectRefType
- IsInstanceOf
- IsSameObject
对象操作
AllocObject
jobject AllocObject(JNIEnv *env, jclass clazz);
分配一个新的Java对象,而不调用对象的任何构造函数。返回对象的引用。
clazz参数不能引用数组类。
链接:
- JNIEnv接口函数表中的索引27。
参数:
- env:JNI接口指针。
- clazz:Java类对象。
返回:
- 返回Java对象,如果无法构造对象,则返回NULL。
抛出:
- InstantiationException:如果该类是接口或抽象类。
- OutOfMemoryError:如果系统内存不足。
代码示例:
/* 分配Java对象 */
jobject myObject = env->AllocObject(myClass);
if(myObject == nullptr) {
printf("无法分配Java对象\n");
}
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指示要调用哪个构造函数方法。此ID必须通过使用<init>作为方法名称和void(V)作为返回类型来调用GetMethodID()来获得。
clazz参数不能引用数组类。
NewObject
程序员将要传递给构造函数的所有参数紧跟在methodID参数之后。NewObject()接受这些参数并将它们传递给程序员希望调用的Java方法。
链接:
- JNIEnv接口函数表中的索引28。
NewObjectA
程序员将要传递给构造函数的所有参数放在一个jvalues类型的args数组中,该数组紧随methodID参数之后。NewObjectA()接受此数组中的参数,并将它们依次传递给程序员希望调用的Java方法。
链接:
- JNIEnv接口函数表中的索引30。
NewObjectV
程序员将要传递给构造函数的所有参数放在一个va_list类型的args参数中,该参数紧随methodID参数之后。NewObjectV()接受这些参数,并将它们依次传递给程序员希望调用的Java方法。
链接:
- JNIEnv接口函数表中的索引29。
参数:
- env:JNI接口指针。
- clazz:Java类对象。
- methodID:构造函数的方法ID。
NewObject的额外参数:
- 构造函数的参数。
NewObjectA的额外参数:
- args:一个包含构造函数参数的数组。
NewObjectV的额外参数:
- args:一个包含构造函数参数的va_list。
返回:
- 返回Java对象,如果无法构造对象,则返回NULL。
抛出:
- InstantiationException:如果该类是接口或抽象类。
- OutOfMemoryError:如果系统内存不足。
- 构造函数抛出的任何异常。
代码示例:
/* NewObject 创建Java对象,传递参数 */
jmethodID myConstructor2 = env->GetMethodID(myClass, "<init>", "(ILjava/lang/String;)V");
jint myInt = 123;
jstring myString = env->NewStringUTF("Hello JNI");
jobject myObject2 = env->NewObject(myClass, myConstructor2, myInt, myString);
if(myObject2 == nullptr) {
printf("无法创建Java对象\n");
}
/* NewObjectA 创建Java对象,传递参数 */
jmethodID myConstructor = env->GetMethodID(myClass, "<init>", "(ILjava/lang/String;)V");
jint myInt = 123;
jstring myString = env->NewStringUTF("Hello JNI");
jvalue args[2];
args[0].i = myInt;
args[1].l = myString;
jobject myObject = env->NewObjectA(myClass, myConstructor, args);
if(myObject == nullptr) {
printf("无法创建Java对象\n");
}
GetObjectClass
jclass GetObjectClass(JNIEnv *env, jobject obj);
返回一个对象的类。
链接:
- JNIEnv接口函数表中的索引31。
参数:
- env:JNI接口指针。
- obj:一个Java对象(不能为NULL)。
返回:
- 返回Java类对象。
代码示例:
/* 获取Java对象的类 */
jclass myObjectClass = env->GetObjectClass(myObject);
if(myObjectClass == nullptr) {
printf("无法获取Java对象的类\n");
}
GetObjectRefType
jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);
返回obj参数所引用对象的类型。参数obj可以是一个局部引用、全局引用或弱全局引用。
链接:
- JNIEnv接口函数表中的索引232。
参数:
- env:JNI接口指针。
- obj:一个局部引用、全局引用或弱全局引用。
- vm:虚拟机实例,从中检索接口。
- env:指针,用于存放当前线程的JNI接口指针的位置。
- version:请求的JNI版本。
返回:
GetObjectRefType函数返回以下枚举值之一,这些值已定义为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。
代码示例:
/* 检查对象是否是指定类的实例 */
jboolean isInstanceOf = env->IsInstanceOf(myObject, myClass);
if(isInstanceOf) {
printf("myObject是MyClass的实例\n");
} else {
printf("myObject不是MyClass的实例\n");
}
/* 比较两个Java对象是否相同 */
jobject myObject2 = env->NewObject(myClass, myConstructor);
jboolean isSameObject = env->IsSameObject(myObject, myObject2);
if(isSameObject) {
printf("myObject和myObject2是同一个Java对象\n");
} else {
printf("myObject和myObject2不是同一个Java对象\n");
}
本文暂时没有评论,来添加一个吧(●'◡'●)