java JNI编程指南

内容发布更新时间 : 2025/7/11 2:43:59星期一 下面是文章的全部内容请认真阅读。

构造函数的方式是很有用的。尽管如此,大部分情况下,你应该使用NewObject,尽量避免使用容易出错的AllocObject/CallNonvirtualVoidMethod方法。

4.4 缓存字段ID和方法ID

获取字段ID和方法ID时,需要用字段、方法的名字和描述符进行一个检索。检索过程相对比较费时,因此本节讨论用缓存技术来减少这个过程带来的消耗。缓存字段ID和方法ID的方法主要有两种。两种区别主要在于缓存发生的时刻,是在字段ID和方法ID被使用的时候,还是定义字段和方法的类静态初始化的时候。

4.4.1 使用时缓存

字段ID和方法ID可以在字段的值被访问或者方法被回调的时候缓存起来。下面的代码中把字段ID存储在静态变量当中,这样当本地方法被重复调用时,不必重新搜索字段ID:

JNIEXPORT void JNICALL

Java_InstanceFieldAccess_accessField(JNIEnv *env, jobject obj) {

static jfieldID fid_s = NULL; /* cached field ID for s */

jclass cls = (*env)->GetObjectClass(env, obj); jstring jstr; const char *str;

if (fid_s == NULL) {

fid_s = (*env)->GetFieldID(env, cls, \

\ if (fid_s == NULL) {

return; /* exception already thrown */ } }

printf(\

jstr = (*env)->GetObjectField(env, obj, fid_s); str = (*env)->GetStringUTFChars(env, jstr, NULL); if (str == NULL) {

return; /* out of memory */ }

printf(\

(*env)->ReleaseStringUTFChars(env, jstr, str);

jstr = (*env)->NewStringUTF(env, \ if (jstr == NULL) {

return; /* out of memory */ }

(*env)->SetObjectField(env, obj, fid_s, jstr); }

由于多个线程可能同时访问这个本地方法,上面方法中的代码很可能会导致混乱,其实没事,多个线程计算的ID其实是相同的。

同样的思想,我们也可以缓存java.lang.String的构造方法的ID: jstring

MyNewString(JNIEnv *env, jchar *chars, jint len) {

jclass stringClass; jcharArray elemArr;

static jmethodID cid = NULL; jstring result;

stringClass = (*env)->FindClass(e

>>灞曞紑鍏ㄦ枃<<
12@gma联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4 ceshi