android中始终需要isCopy字段吗?

时间:2015-06-23 02:42:06

标签: java android c++ java-native-interface

我通常使用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?它取决于平台吗?或取决于运行时间条件?或其他条件?

3 个答案:

答案 0 :(得分:1)

永远不需要。

  

大多数情况下,您将NULL作为isCopy参数传递。

- Java Native Interface。程序员指南和规范。 1999。盛亮。

  

您可以通过传入isCopy参数的非NULL指针来确定是否复制了数据。这很少有用。

- Andriod Developer JNI Tips

并且,总是必须在每次成功调用GetStringUTFChars时调用ReleaseStringUTFChars。

答案 1 :(得分:1)

正如@ tom-blodget所说,如果结果不是ReleaseStringUTFChars,你应该<{>>总是在GetStringUTFChars后调用NULL

isCopy只允许您应用优化:

  • 如果isCopytrue,您可以安全地修改返回的缓冲区,而不必担心Java端的String会受到影响。
  • 如果isCopyfalse,则必须分配另一个缓冲区并制作副本(如果需要进行修改)。请不要直接修改返回的缓冲区!这是因为在Java中,String类型是不可变的。所有Java代码都希望String对象永远不会更改。

答案 2 :(得分:0)

VM可以通过两种方式处理GetStringUTFChars方法。在某种程度上,VM将为本机字符串(相当于java字符串)分配内存,而另一方面,VM将只提供一个指向java字符串的直接指针。前一种情况isCopy将为TRUE,后一种情况为FALSE。

用户不知道此行为,并且仅在运行时由VM决定。因此,始终建议在释放本机字符串之前检查isCopy值。如果isCopy为FALSE并且你释放了实际修改java字符串的本地字符串,这实际上破坏了java.lang.String类的不变性规则。