编译时期

首先,我们先来合理的推断一下,当我们在代码中使用String s = "";的形式来定义String对象的时候,""中字符的个数有没有限制呢?既然是合理的推断,那就要要足够的依据,所以我们可以从String的源码入手,根据public String(char value[], int offset, int count)的定义,count是int类型的,所以,char value[]中最多可以保存Integer.MAX_VALUE个,即2147483647字符。(jdk1.8.0_73)但是,实验证明,String s = "";中,最多可以有65534个字符。如果超过这个个数。就会在编译期报错。

public static void main(String[] args) {String s = "a...a";// 共65534个aSystem.out.println(s.length());String s1 = "a...a";// 共65535个aSystem.out.println(s1.length());
}

以上代码,会在String s1 = "a…a";// 共65535个a处编译失败:

✗ javac StringLenghDemo.java
StringLenghDemo.java:11: 错误: 常量字符串过长

明明说好的长度限制是2147483647,为什么65535个字符就无法编译了呢?

当我们使用字符串字面量直接定义String的时候,是会把字符串在常量池中存储一份的。那么上面提到的65534其实是常量池的限制。

常量池中的每一种数据项也有自己的类型。Java中的UTF-8编码的Unicode字符串在常量池中以CONSTANT_Utf8类型表示。

CONSTANTUtf8info是一个CONSTANTUtf8类型的常量池数据项,它存储的是一个常量字符串。常量池中的所有字面量几乎都是通过CONSTANTUtf8info描述的。CONSTANTUtf8_info的定义如下:

CONSTANT_Utf8_info {u1 tag;u2 length;u1 bytes[length];
}

由于本文的重点并不是CONSTANTUtf8info的介绍,这里就不详细展开了,我们只需要我们使用字面量定义的字符串在class文件中,是使用CONSTANTUtf8info存储的,而CONSTANTUtf8info中有u2 length;表明了该类型存储数据的长度。

u2是无符号的16位整数,因此理论上允许的的最大长度是2^16=65536。而 java class 文件是使用一种变体UTF-8格式来存放字符的,null 值使用两个 字节来表示,因此只剩下 65536- 2 = 65534个字节。

关于这一点,在the class file format spec中也有明确说明:

The length of field and method names, field and method descriptors, and other constant string values is limited to 65535 characters by the 16-bit unsigned length item of the CONSTANTUtf8info structure (§4.4.7). Note that the limit is on the number of bytes in the encoding and not on the number of encoded characters. UTF-8 encodes some characters using two or three bytes. Thus, strings incorporating multibyte characters are further constrained.

也就是说,在Java中,所有需要保存在常量池中的数据,长度最大不能超过65535,这当然也包括字符串的定义咯。

运行时期

上面提到的这种String长度的限制是编译期的限制,也就是使用String s= "";这种字面值方式定义的时候才会有的限制。

那么。String在运行期有没有限制呢,答案是有的,就是我们前文提到的那个Integer.MAX_VALUE ,这个值约等于4G,在运行期,如果String的长度超过这个范围,就可能会抛出异常。(在jdk 1.9之前)

int 是一个 32 位变量类型,取正数部分来算的话,他们最长可以有

2^31-1 =2147483647 个 16-bit Unicodecharacter2147483647 * 16 = 34359738352 位
34359738352 / 8 = 4294967294 (Byte)
4294967294 / 1024 = 4194303.998046875 (KB)
4194303.998046875 / 1024 = 4095.9999980926513671875 (MB)
4095.9999980926513671875 / 1024 = 3.99999999813735485076904296875 (GB)

有近 4G 的容量。

Java中的String长度限制相关推荐

  1. 我说我精通字符串,面试官竟然问我Java中的String有没有长度限制!?

    String是Java中很重要的一个数据类型,除了基本数据类型以外,String是被使用的最广泛的了,但是,关于String,其实还是有很多东西容易被忽略的. 就如本文我们要讨论的问题:Java中的S ...

  2. Java中的String、StringBuilder、StringBuffer

    Java中的String是个永恒的话题,直说我想说的. 1.String 是永远不会变的,传递的引用是一个Copy,无论刮风下雨,它都在自己的小窝里呆的好好的. 2.重载"+"和S ...

  3. 剖析java中的String之__拼接

    剖析java中的String之__拼接 分类: java 2011-08-24 17:46 31人阅读 评论(0) 收藏 举报 出处, http://blog.csdn.net/izard999/ar ...

  4. Java中的String.hashCode()方法可能有问题?

    过去几天,我一直在浏览Reddit上的一篇文章.这篇文章看得我要抓狂了.文章指出,Java中的String.hashCode()方法(将任意长度的字符串对象映射成32位int值)生成的哈希值存在冲突. ...

  5. java中的数组长度的计算

    讲到了java中数组的长度的计算,那就是少不了了那个java中的数组的定义. int a[]=new int[5]; String[]str=new String[]; String[]str=new ...

  6. 【JAVA SE】java中的String类

    目录 String类 什么是String类? String类的定义方式 String的内部 如何求字符串长度呢? String类对象的比较 字符串查找 总结charAt 字符串转化 数字与字符串之间的 ...

  7. Java 中的 String、StringBuilder、StringBuffer 的区别

    目录 一.是什么? 二.区别是? 1. 运行速度(执行速度) 2. 线程安全 三.小结 四.加餐 一.是什么? String 不可变字符序列 String 是字符串常量,其对象一旦创建之后该对象是不可 ...

  8. Java中的String类占用多大的内存

    写在前面 对于Java中的String类占用多大的内存空间这个问题,是最近面试中问的比较多的一个问题.很多小伙伴的回答的都不是很正确,有说不占空间的,有说1个字节的,有说2个字节的,有说3个字节的,有 ...

  9. 深入理解Java中的String(原地址https://www.cnblogs.com/xiaoxi/p/6036701.html)

    深入理解Java中的String 一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class Stringimplem ...

最新文章

  1. python中tkinter圆弧_Tkinter(Python)中弧的选项
  2. webBrowse无法正常显示Excel
  3. fix--向零方向取整
  4. aliyun tianchi ai contest meeting note
  5. Java 的这些坑,你踩到了吗?
  6. WordPress 主题教程 #5c:日志元数据
  7. 理论计算机图形渲染技术是否已经到了没有什么可以研究的地步了?
  8. 系统板I/O端口地址分配(一)
  9. 用inno 打包程序 学习之路(转载)
  10. kangle源码idc下载_kangle康乐idc商务系统搭建源码+教程
  11. 人、猕猴、小鼠静息态三重网络
  12. 局域网文件服务器带宽,高带宽局域网
  13. 把桌面路径改到D盘,忘记新建文件夹,D盘所有文件跑到桌面怎么办?
  14. 一次哔哩哔哩面试经历,内容太过真实
  15. 0030-用OpenCV的inpaint函数做图像的污点修复
  16. html标题字体重叠,如何在HTML和CSS的段落标题上方显示堆叠的字体超棒图标?
  17. android 分享二维码图片到微信QQ(url地址字符串生成二维码图片、分享二维码图片到微信QQ)
  18. 【洛谷题解】P2404 自然数的拆分问题
  19. 字节转字符的三种方式
  20. ESP32 (WIFI)-AP、STA模式(14)

热门文章

  1. java怎么定义一维数组_Java定义一个一维数组有哪几种方法
  2. Android开发:LocationManager获取经纬度及定位过程(附demo)
  3. Python、Cython、CPython的简单对比
  4. Oracle 中LONG RAW BLOB CLOB类型介绍
  5. WPF中MaterialDesignThemes前端框架的使用(超详细图解步骤)
  6. 计算机word知识试题及答案,全国计算机等级考试Word试题及答案(2)
  7. 蓝牙路由器解决方案行业应用
  8. 飞桨 x Graphcore IPU适配方案深度解读与硬件介绍 | 洞见AI硬件
  9. Spring都没弄明白凭什么拿高薪,Android研发岗面试复盘总
  10. 如何零成本实现微信公众号自助查券返利机器人(四)