String Compact引发JNI性能问题,如何在C++端直接访问字符串内容?
JNI 直接访问 Compact String 内容的方案
不需要借助反射,Java 9及以上的JNI已经提供了适配Compact String的原生API,可以直接无拷贝访问字符串底层内容:
先通过
GetStringType函数判断字符串的编码类型:JNIEnv* env = ...; jstring javaStr = ...; jint strType = env->GetStringType(javaStr);返回值为
JNI_LATIN1(对应Latin1编码的Compact String)或JNI_UTF16(对应UTF-16编码的字符串)。根据编码类型选择对应访问方式:
- 若为
JNI_LATIN1:调用GetStringUTFChars,此时返回的指针直接指向底层的Latin1字节数组(Latin1与UTF-8单字节部分完全兼容),不会触发拷贝:jboolean isCopy; const jbyte* latin1Bytes = reinterpret_cast<const jbyte*>(env->GetStringUTFChars(javaStr, &isCopy)); // 此时isCopy会被设为JNI_FALSE,直接访问即可 - 若为
JNI_UTF16:调用GetStringCritical,与之前的逻辑一致,可直接访问UTF-16字符数组,无拷贝:jboolean isCopy; const jchar* utf16Chars = env->GetStringCritical(javaStr, &isCopy); // 直接访问utf16Chars
- 若为
如果需要兼容Java 8及更早版本,才需要考虑通过反射获取String内部的value字节数组,但这种方式依赖String的内部实现,版本兼容性差,不推荐使用。
内容的提问来源于stack exchange,提问作者pippo
相关产品推荐
相关产品推荐

