为了最大限度地减少复制操作,并直接访问字符串的字符串内容,JNI提供了GetStringCritical,该功能一直运行良好.然而,随着Java中"字符串压缩"的引入,字符串编码可以是Latin1或UTF16.在讲英语的地区,绝大多数字符可以使用Latin1表示,因此大多数字符串对象在内部使用Latin1存储.这在使用GetStringCritical时造成了一个尴尬的情况,因为包含的字符串将被强制代码转换为UTF16,这意味着一定的复制操作.

还有没有办法在C++端直接访问字符串内容?我们真的需要求助于反射来从字符串中检索byte[]值吗?

推荐答案

还有没有办法在C++端直接访问字符串内容?

不是以一种安全和便携的方式.如果您try 在C++中直接访问字符串Content(即,不使用GetStringGetCriticalString),您可能会很不幸地发现,当您访问堆 node 时,GC会移动包含它的内容的堆 node .

我们真的必须求助于反射来从String中检索byte[]值吗?

这将是一个坏主意.它将是不可携带的...从JNI/C++使用反射比从Java使用反射要少more expensive倍.

注意,在Java 11和Java 17之间的某个时候,JNI GetStringCritical的C++实现发生了变化,现在always复制了字符.

我还没有研究他们为什么改变这一点,但如果你愿意努力,在提交消息中有could be个线索,在问题跟踪器中有相关的问题.代码位于"src/hotpot/share/prims/jni.cpp"或"hotpot/src/share/prims/jni.cpp"中,具体取决于OpenJDK版本.

在我看来,你最好不要试图优化这一点.如果您确实对其进行了优化,您会发现需要针对不同的Java版本进行不同的优化.

Java相关问答推荐

在数组中使用意想不到的结果

'在使用apache poi生成Excel数据透视表时,行标签显示为第一列标题,并显示分类汇总

在Spring Boot中测试时出现SQL语法错误

Mongo DB Bson和Java:在子文档中添加和返回仅存在于父文档中的字段?

如何粘合(合并)文件Lucene?

AlarmManager没有在正确的时间发送alert

@ IdClass with @ Inheritance(策略= InheritanceType. SINGLE_TABLE)

给定Java枚举类,通过值查找枚举

如何在Java中从XML中获取特定的 node ,然后将其删除?

Java流传输一个列表并创建单个对象

GetChildren().emoveAll()不会删除 node

使用正则表达式从字符串中提取多个值

在Oracle JDBC连接中,连接失效和身份验证失效是什么意思?

JFree Chart从图表中删除边框

Android无法在Java代码中调用Kotlin代码,原因是在Companion中使用Kotlin枚举时

无法在Java中获取ElastiCache的AWS CloudWatch指标

在Java中比较同一多维数组的两个不同的字符串元素

如何修复Spring Boot应用程序中的RestDocumentationGenerationException:java.io.FileNotFoundException:/curl-request.adoc(只读文件系统)?

让标签占用JavaFX中HBox的所有可用空间

spring 数据Elastic search 与 spring 启动数据Elastic search 之间的区别是什么?