You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JNI中获取Kotlin HashMap中存储的String列表值?

JNI获取Kotlin HashMap中ArrayList值的崩溃问题解决方法

你的JNI代码存在三个核心问题导致崩溃,逐一修正即可解决:

1. 方法签名错误

HashMap的get方法签名并非(Ljava/lang/String;)[Ljava/lang/String;,原因如下:

  • 泛型在JNI层面会被类型擦除,get方法的参数实际是Object类型,参数部分签名为(Ljava/lang/Object;)
  • get方法返回的是Object(你存储的是ArrayList对象,并非直接的字符串数组),返回值部分签名为Ljava/lang/Object;
    正确的方法签名应为:(Ljava/lang/Object;)Ljava/lang/Object;

2. 参数传递错误

直接将C字符串字面量强转为jstring是无效操作,必须通过JNI的NewStringUTF方法创建合法的jstring对象。

3. 类型转换错误

HashMap中存储的是ArrayList<String>,调用get方法返回的是ArrayList对象,不能直接转为jobjectArray,需要先调用ArrayList的toArray方法将其转换为字符串数组。

修正后的完整代码

// 1. 获取HashMap类与get方法ID
jclass hashMapClass = env->GetObjectClass(hm);
jmethodID getMethodId = env->GetMethodID(hashMapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");

// 2. 创建合法的jstring类型键值
jstring key = env->NewStringUTF("in1");

// 3. 调用get方法获取ArrayList对象
jobject arrayListObj = env->CallObjectMethod(hm, getMethodId, key);

// 及时释放局部引用,避免内存泄漏
env->DeleteLocalRef(key);
env->DeleteLocalRef(hashMapClass);

if (arrayListObj == nullptr) {
    // 处理键不存在的场景
    return nullptr;
}

// 4. 获取ArrayList类与toArray方法ID
jclass arrayListClass = env->GetObjectClass(arrayListObj);
jmethodID toArrayMethodId = env->GetMethodID(arrayListClass, "toArray", "()[Ljava/lang/Object;");

// 5. 调用toArray得到Object数组,再转换为String数组
jobjectArray objectArray = (jobjectArray)env->CallObjectMethod(arrayListObj, toArrayMethodId);
jclass stringClass = env->FindClass("java/lang/String");
jobjectArray stringArray = (jobjectArray)env->NewObjectArray(env->GetArrayLength(objectArray), stringClass, nullptr);

for (int i = 0; i < env->GetArrayLength(objectArray); i++) {
    jobject strObj = env->GetObjectArrayElement(objectArray, i);
    env->SetObjectArrayElement(stringArray, i, strObj);
    env->DeleteLocalRef(strObj);
}

// 释放剩余局部引用
env->DeleteLocalRef(arrayListClass);
env->DeleteLocalRef(objectArray);
env->DeleteLocalRef(arrayListObj);
env->DeleteLocalRef(stringClass);

// stringArray即为最终需要的字符串数组

额外注意事项

  • JNI中局部引用数量有限,务必及时释放不再使用的引用,防止内存泄漏
  • 若Kotlin使用mutableMapOf等其他Map实现,核心逻辑一致,因为它们都继承自Java的Map接口
  • 若无需转换为数组,也可直接调用ArrayList的get(int)方法逐个获取元素

内容的提问来源于stack exchange,提问作者Edward Snowden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:32:26