我通常使用java处理字符串的JNI代码就是这样:
jboolean isCopy_something;
const char* something=env->GetStringUTFChars(somethingFromJava,&isCopy_something);
if(isCopy_something==JNI_TRUE){
env->ReleaseStringUTFChars(somethingFromJava,something);
}
我认为如果我需要为Java中的每个字符串添加一个额外的jboolean,它会严重影响代码的可读性,除了jboolean之外,我还需要一个if else语句来包装ReleaseStringUTFChars。
我记得我看过一些代码只传递NULL而不是isCopy的地址。
我可以在不检查android中的isCopy的情况下调用ReleaseStringUTFChars吗?
我搜索了一些关于isCopy字段的帖子,但仍然没有真正理解ReleaseStringUTFChars中isCopy字段的功能:isCopy何时成为JNI_TRUE,何时成为JNI_FALSE?它取决于平台吗?或取决于运行时间条件?或其他条件?
答案 0 :(得分:1)
永远不需要。
大多数情况下,您将NULL作为isCopy参数传递。
- Java Native Interface。程序员指南和规范。 1999。盛亮。
您可以通过传入isCopy参数的非NULL指针来确定是否复制了数据。这很少有用。
并且,总是必须在每次成功调用GetStringUTFChars时调用ReleaseStringUTFChars。
答案 1 :(得分:1)
正如@ tom-blodget所说,如果结果不是ReleaseStringUTFChars
,你应该<{>>总是在GetStringUTFChars
后调用NULL
。
isCopy
只允许您应用优化:
isCopy
为true
,您可以安全地修改返回的缓冲区,而不必担心Java端的String
会受到影响。isCopy
为false
,则必须分配另一个缓冲区并制作副本(如果需要进行修改)。请不要直接修改返回的缓冲区!这是因为在Java中,String
类型是不可变的。所有Java代码都希望String
对象永远不会更改。答案 2 :(得分:0)
VM可以通过两种方式处理GetStringUTFChars方法。在某种程度上,VM将为本机字符串(相当于java字符串)分配内存,而另一方面,VM将只提供一个指向java字符串的直接指针。前一种情况isCopy将为TRUE,后一种情况为FALSE。
用户不知道此行为,并且仅在运行时由VM决定。因此,始终建议在释放本机字符串之前检查isCopy值。如果isCopy为FALSE并且你释放了实际修改java字符串的本地字符串,这实际上破坏了java.lang.String类的不变性规则。