做项目,客户端这里自己模拟json数据时,一时没忍住搞得json字符串太长了(idea上大概有600多行吧),这个问题就蹦出来了。老方法直接google、百度然后看到一堆有关String 字符串常量池字符最大限制的文章,这些前辈都是从jvm的运行时常量池的常量表占的内存数,从原理上讲解了常量池所能容纳的最大字符数。对于不了解jvm的同学来说,啥无符号数、有符号数、u1、u2之类的看着看着就懵逼了。俗话说学而不思则罔,这里我就从常量池和内存区域的角度来简单分析下自己的观点。相对jvm的那套理论感觉更容易使人接受。

一、背景

/**

* Created by sunnyDay on 2019/11/19 17:31

*

* double check

*/

public class Jsons {

private volatile static Jsons instance;

private Jsons() {

}

public static Jsons getInstance() {

if (instance == null) {

synchronized ("lock") {

if (instance == null) {

instance = new Jsons();

}

}

}

return instance;

}

public String getConstellationTestJson(){

return "很长的json,粘贴的下图json文件的字符串"

}

}

public class Test {

public static void main(String[] args) {

// 编译时直接报错

System.out.println(Jsons.getInstance().getConstellationTestJson());

}

}

如上:就是一个工具类,提供json字符串,为了演示我单独抽出来放idea中跑了下。

二、字符串String的最大长度

理论解析:

传送门

三、我的理解及其解决方案

理论性的东西前辈们都总结的差不多了,这里就添加下个人理解。及其解决方案。

1、首先理解下jvm方法区的运行时池

好处:

常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。

注意点:

1、java中基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean。这里就就只说字符传常量池相关。

2、java中以双引号引住的内容就是字符创常量,编译时就会吧双引号引的内容放入字符创常量池。

2、字符创常量池的实战参考(一定要看)

String stra = "abcd"; // 对象存储在常量池中

String strb = new String("abcd");// new 就是在堆中分配了新的地址

System.out.println(stra==strb);//false

String str1 = "str";

String str2 = "ing";

String str3 = "str" + "ing";

String str4 = str1 + str2; //对于字符串变量的“+”连接表达式,它所产生的新对象都不会被加入字符串池中,其属于在运行时创建的字符串,具有独立的内存地址,所以不引用自同一String对象。

System.out.println("string" == "str" + "ing");// true 只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入常量池中

System.out.println(str3 == str4);//false

String str5 = "string";

System.out.println(str3 == str5);//true

注意点:

1、+号连接的对象引用

2、+号链接的字符串常量

3、解决方案

不让放那么多,这里放不了我们不放这里或者这里放少点。不ojbk了。太聪明了嘿嘿嘿!!!

(1)错误解决方式

public String getConstellationTestJson(){

return "很长的json一半"+"很长的json一半";

}

这里+号拼接的结果还是会放进常量池的。参考实战。

(2)正确解决方式

```java

public String getConstellationTestJson(){

String s1 = "很长的json一半"; //内容放常量池

String s2 = "很长的json一半"; // 内容放常量池

return s1+s2; // 结果具有了新的内存地址(堆中)

}

解决,s1+s2的结果会放入新的内存地址中,参考上文实战。

(3)正确解决 使用new String 拆分拼接

(4)使用StringBuild#StringBuffer 拆分拼接

(5)通过文件读取(这里使用安卓的assets为例子)

private String getAssetsData() {

String result = "";

try {

InputStream mAssets = getAssets().open("dream.json");

int lenght = mAssets.available();

byte[] buffer = new byte[lenght];

mAssets.read(buffer);

mAssets.close();

result = new String(buffer, StandardCharsets.UTF_8); // 关键之处

return result;

} catch (IOException e) {

e.printStackTrace();

return result;

}

}

4、感悟

只要堆的内存不满,或者拆分的子字符串满足常量池大小,就基本没啥问题了。

5、推荐参考:java内存区域与内存溢出异常的常量池部分内容

————————————————

版权声明:本文为CSDN博主「dev晴天」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_38350635/article/details/103495951

java多行字符串常量,【转】Error,java对常量池来说字符串xxx的UTF8表示过长的解决及其理解...相关推荐

  1. Error: java.io.IOException: Spill failed,Error: java.lang.NullPointerException以及hadoop输出结果为空的可能性。

    首先先说第一种:Error: java.io.IOException: Spill failed 一般出现这种错误你都可以去看看你的自定义bean类的序列化方法对应是不是写错了,一般来说都是这个问题虽 ...

  2. Error,java对常量池来说字符串xxx的UTF8表示过长

    客户端这里自己模拟json数据时,一时没忍住搞得json字符串太长了(idea上大概有600多行吧),这个问题就蹦出来了.老方法直接google.百度然后看到一堆有关String 字符串常量池字符最大 ...

  3. java 命令行 解析_如何在Java中解析命令行参数?

    小编典典 例如,这是你commons-cli用来解析2个字符串参数的方法: import org.apache.commons.cli.*; public class Main { public st ...

  4. java 9行代码_GitHub - lqy0702/RxjavaYxj: 可能是迄今为止最简洁,最形象化的Rxjava核心源码讲解。理解9行核心代码,带你完全掌握Rxjava运行机制。...

    本文已授权微信公众号:鸿洋(hongyangAndroid)在微信公众号平台原创首发 你是不是看过了很多分析Rxjava源码的文章,但依旧无法在心中勾勒出Rxjava原理的样貌.是什么让我们阅读Rxj ...

  5. 对于常量池来说, 字符串 *** 的 UTF8 表示过长怎么解决

    首先说一下为什么会出现这种情况. 1.解释长度问题: 定义一个字符类型的变量究竟能有多长? 答案:65536,也就是二的16次方,因为常量在class文件的规范中, CONSTANT_Utf8_inf ...

  6. 02_Keil5报错 error: #5: cannot open source input file “XXX.h”: No such file or directory解决方法

    Keil5  error: #5: cannot open source input file "led.h": No such file or directory 是找不到包含文 ...

  7. 解决IntelliJ IDEA报错Error: java: 错误: 不支持发行版本 XX

    解决IntelliJ IDEA报错Error: java: 错误: 不支持发行版本 XX 解决方法 1 解决方法 2 解决方法 3   笔者在做代码重构的时候,以前记得运行正常的代码,如今一直报错,百 ...

  8. java中的字符串常量池_java字符串常量池

    字符串常量池SCP jdk1.6是放在永久代(8中叫方法区或叫元空间)中; jdk1.7+中,字符串常量池放入了堆中,注意运行时常量依然存放在方法区,例如,Integer a = 40:Java在编译 ...

  9. Java中String类、字符串常量池、字符串常用方法

    String类: String代表字符串类,java中所有双引号中的内容都称为字符串,如:"hello".字符串是不可改变的,因此字符串是可以共享使用的,相当于char字符数组,但 ...

最新文章

  1. 干货丨【看图识算法】这是你见过最简单的 “算法说明书”
  2. JMS中queue和topic区别
  3. .NET 开源软件开发BIM工具包xBIM
  4. WinSCP实现Ubuntu与 Windows 文件共享方法
  5. 【Java学习】JDBC可以再深一点理解
  6. 加州理工学院对高超声速飞行的早期研究
  7. DedeCMS高仿老版chinaz站长网模板
  8. 使用计算机在什么上传输,MODEM的作用是使计算机数据能在什么上传输
  9. 数据--第21课-递归课后练习
  10. 计算机视觉论文-2021-09-14
  11. jquery点击图片放大功能
  12. spring框架特点
  13. 人人网主页登录_“人人网”回来了!网友炸锅:有人想找前女友,有人想删“黑历史”……...
  14. 风暴数码论坛教程--官方和第三方ROM的提取与分解
  15. RMON 远端网络监控
  16. 商业研究(19):变革家,专注创业项目分析,重点服务广大散户(建议股权众筹者谨慎买入。。。)
  17. 百度云加速提升网站访问速度
  18. 可以不学html直接学vue吗,一个只学过HTML,CSS,JS的前端初学者在学习Vue.js之前还需要学习哪些知识?...
  19. 智能写作软件-免费智能写作文章内容软件
  20. CRMEB微信公众号安装说明

热门文章

  1. 实现本地 Markdown 博客文章自动发送到博客园
  2. 良心安利砖ps后期素材素材网站
  3. python nlp 句子提取_python nlp 句子提取_《用Python进行自然语言处理》第7章 从文本提取信息...
  4. List集合遍历时如何删除元素
  5. Eclipse与MyEclipse简介
  6. InVEST模型 | 软件安装与固碳模块的使用
  7. [渝粤教育] 山东财经大学 采购与仓储管理 参考 资料
  8. tomcat登录违反协议_java.sql.sqlexception: 违反协议
  9. 流量限制(rate-limiting)
  10. ios 绘制线框_iOS使用Charts框架绘制折线图