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

一、情景再现

/*** Created by sunnyDay on 2019/11/19 17:31* <p>* 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中跑了下。这样bug就mock出来了。

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

看到过这样一篇文章,字符串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);//falseString 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);//falseString str5 = "string";System.out.println(str3 == str5);//true

注意点:
1、+号连接的对象引用
2、+号链接的字符串常量

3、解决方案

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

(1)错误解决方式

 public String getConstellationTestJson(){return "很长的json一半"+"很长的json一半";
}

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

(2)正确解决方式

```javapublic 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、感悟

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

Error,java对常量池来说字符串xxx的UTF8表示过长相关推荐

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

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

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

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

  3. java string 常量池_用了这么久Java String,你真的懂字符串常量池吗?

    字符串问题可谓是 Java 中经久不衰的问题,尤其是字符串常量池经常作为面试题出现.可即便是看似简单而又经常被提起的问题,还是有好多同学一知半解,看上去懂了,仔细分析起来却又发现不太明白. 本文以 J ...

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

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

  5. 详解JVM常量池、Class常量池、运行时常量池、字符串常量池(心血总结)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  6. 读取字符串字符时出错_JVM | 运行时常量池和字符串常量池及intern()

    本文知识点 这一块的知识点,一直都是最为混乱的,网上很多博客有的都自相矛盾,因此,这一块需要深入学习,本文以JDK11为基础,尽量参考官方文档 静态常量池 运行时常量池及字符串的引用 各种String ...

  7. 常量池之字符串常量池String.intern()

    运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现 ...

  8. Java String 常量池理解

    Java String 常量池理解 String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以 ...

  9. class常量池、运行时常量池 和 字符串常量池 的区别

    文章目录 一.概念 1.class常量池(Constant Pool) 1.1.字面量 1.2.符号引用 2.Runtime Constant Pool( 运行时常量池 ) 3.String Pool ...

最新文章

  1. 浅谈likely与unlikely
  2. VMware14黑屏问题
  3. python中modify是什么意思_python – Django中的override_settings和modify_settings有什么区别?...
  4. maven工程下 读取resource下配置文件
  5. 在URL里传入数组到HTML 里。
  6. P4196-[CQOI2006]凸多边形/[模板]半平面交【计算几何】
  7. #ifndef、#def、#endif等宏是什么意思
  8. 虚拟资源拳王公社:什么是虚拟资源自动化?为什么虚拟产品可以自动化赚,虚拟资源自动化有什么
  9. 函数的基本知识,定义,调用,参数,返回值,说明文档,函数的嵌套及应用
  10. IT人才需要怎样的沟通表达能力
  11. Excel2013每次打开都弹出配置进度窗口的分步解决办法
  12. 《NPDP 产品经理认证知识体系指南》读书笔记
  13. js中undefined
  14. Java 进阶 hello world! - 中级程序员之路
  15. 零基础“复刻”经典飞机大战小程序游戏【一篇文使用 IVX 轻松实战5】
  16. sql查询当天交易总额最大的用户信息_如何分析交易记录? 因为后面要分析“每种类型用户的总交易金额”,所以保留左表(用户交易记录表)中的全部用户数据。 【题目】 某商场为了分析用... - 雪球...
  17. Android用mediaPlayer.prepare()报错
  18. 第十期-Linux内核补丁源码分析(2)
  19. 易语言三款浏览器支持库哪款支持页游更好?
  20. python调用ip摄像头为什么打不开_怎么用python的opencv库打开ip摄像头

热门文章

  1. cuda、Nvidia driver、GCC版本对应关系
  2. HOTMAIL搭建企业邮箱
  3. 阻容感基础05:电容器原理(1)-电容器模型
  4. 快递鸟基于java功能打印电子面单api接口
  5. 如何将二维码数据换行显示
  6. MATLAB 各类二维渐变图
  7. tl-wdr5620虚拟服务器设置,TP-Link TL-WDR5620路由器手机怎么设置?
  8. 操作系统————应用题
  9. iphone 如何运行android,iPhone成功运行Android,厉害~
  10. 36 岁开发者应聘被拒?这 3 位 50 岁程序员的生存秘籍送给你!