admin管理员组文章数量:1567290
文章目录
- 1.发生问题的场景
- 2.解决问题
- 3.问题的原因
- 另外
- 4.参考
1.发生问题的场景
我在用java获取一个接口的大JSON字符串,并赋值给String常量时,遇到了java: 常量字符串过长这个报错。
2.解决问题
2.1 可以使用StringBuilder(线程不安全)或StringBuffer(线程安全,即append方法被synchronize修饰)的append方法来拼接一个String,最后再通过toString()方法转为String即可
2.2 也可以使用 += 符号来拼接字符串,在javac中,String的 += 符号被重载为了StringBuilder的append方法,有兴趣的可以去了解一下
3.问题的原因
那么为啥会报这个问题呢?这是由于当前String字符串是来自常量池中的引用,而常量池中的String是定长的,如下:
翻阅jvm规范发现:
在java中,常量String的结构体如下,其中的string_index指针指向常量池的一个条目,这个条目的结构体格式为CONSTANT_Utf8_info
我们来看这个CONSTANT_Utf8_info 结构体,由下图可知一个String类型的常量的最大长度为2^16-1,但事实真的如此吗?
经过测试,我发现实际最多存2^16-1-1个字符,这是为什么呢?我先去下载了javac的源码(在lib/scr.zip中),我在\lib\src\jdkpiler\com\sun\tools\javac\jvm|Gen.java中看到了:
而这个PoolWriter.MAX_STRING_LENGTH的值为:
所以可以得出,javac允许常量String保存的最大字节数为0xFFFF-1即2^16-2 !!!
而为什么要使用StringBuilder、StringBuffer或者+=呢?因为它们能保证当前的String字符串的引用是来自堆中的引用,而堆中的String是可以动态分配长度的。
另外
关于StringBuilder.append()与+=符号的区别:append()方法是在原始的String字符串后面继续添加,而+=符号会在堆中创建一个新的字符串,并修改原来的对引用为这个新的字符串地址!
综上,使用StringBuilder/StringBuffer的append()方法为最优解。
4.参考
1.java String 到底有多长?String超出长度怎么解决?
2.字符串String的+和+=及循环操作String的原理
版权声明:本文标题:java: 常量字符串过长 报错的解决方法及原因 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1725723780a1038694.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论