string长度问题
原文地址:
https://toutiao.io/shares/2029578/url
String是Java中很重要的一个数据类型,除了基本数据类型以外,String是被使用的最广泛的了,但是,关于String,其实还是有很多东西容易被忽略的。
就如本文我们要讨论的问题:Java中的String有没有长度限制?
这个问题要分两个阶段看,分别是编译期和运行期。不同的时期限制不一样。
1
编译期
首先,我们先来合理的推断一下,当我们在代码中使用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个a
System.out.println(s.length());
String s1 = "a...a";// 共65535个a
System.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,这当然也包括字符串的定义咯。
2
运行期
上面提到的这种String长度的限制是编译期的限制,也就是使用String s= "";这种字面值方式定义的时候才会有的限制。
那么。String在运行期有没有限制呢,答案是有的,就是我们前文提到的那个Integer.MAX_VALUE ,这个值约等于4G,在运行期,如果String的长度超过这个范围,就可能会抛出异常。(在jdk 1.9之前)
int 是一个 32 位变量类型,取正数部分来算的话,他们最长可以有
2^31-1 =2147483647 个 16-bit Unicodecharacter 2147483647 * 16 = 34359738352 位
34359738352 / 8 = 4294967294 (Byte)
4294967294 / 1024 = 4194303.998046875 (KB)
4194303.998046875 / 1024 = 4095.9999980926513671875 (MB)
4095.9999980926513671875 / 1024 = 3.99999999813735485076904296875 (GB)
有近 4G 的容量。
string长度问题的更多相关文章
- java String长度与varchar长度匹配理解(字符和字节长度理解)
java String长度与varchar长度匹配理解(字符和字节长度理解) string中的length()长度,返回的是char的数量,每个char可以存储世界上任何类型的文字和字符,一个char ...
- C# 与数据库中字段类型 Int16(short), Int32(int), Int64(long)的取值范围、区别 。string长度
一开始看到Int16, Int32, Int64这三种类型就觉得有点怪, 为什么要整个数字结尾的, 挺怪的. 昨天互相想到, ms这么干就是想让大家一眼就知道这个数据类型占多大空间吧. Int8, 等 ...
- Java int转string 长度不足左补0
最近项目中用到这个需求,我试了两个方法都可以实现 方法一:(推荐) String s=String.format("%010d", 123)//123为int类型,0代表前面要补的 ...
- String长度限制?
String我们在开发和学习中会经常用到,但对String类型的取值范围我们并不明确. String底层是char数组,并未标明长度限制.java中可以对数组指定长度,如果不指定就以实际元素来指定 p ...
- 我说精通字符串,面试官竟然问我 Java 中的 String 有没有长度限制?
String 是 Java 中很重要的一个数据类型,除了基本数据类型以外,String 是被使用的最广泛的了,但是,关于 String,其实还是有很多东西容易被忽略的. 就如本文我们要讨论的问题:Ja ...
- 我说我精通字符串,面试官竟然问我Java中的String有没有长度限制!?|附视频讲解
关于String有没有长度限制的问题,我之前单独写过一篇文章分析过,最近我又抽空回顾了一下这个问题,发现又有了一些新的认识.于是准备重新整理下这个内容. 这次在之前那篇文章的基础上除了增加了一些验证过 ...
- Swift3 - String 字符串、Array 数组、Dictionary 字典的使用
Swift相关知识,本随笔为 字符串.数组.字典的简单使用,有理解.使用错误的地方望能指正. ///************************************************** ...
- string黑科技
1. string对象的定义和初始化以及读写 string s1; 默认构造函数,s1为空串string s2(s1); 将s2初始化为s1的一个副本string s3("valuee&qu ...
- Java总结篇系列:Java String
String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. 1 ...
随机推荐
- ASP.NET Core webapi json 返回时间格式问题
网站找了几个方案不好使,比如: 1: services.AddMvc().AddJsonOptions(opt => { opt.SerializerSettings.DateFormatStr ...
- LOJ2001 SDOI2017 树点涂色 LCT、线段树
传送门 注意到每一次\(1\ x\)操作相当于一次LCT中的access操作.由LCT复杂度证明可以知道access的总次数不会超过\(O(nlogn)\),我们只需要模拟这个access的过程并在其 ...
- BZOJ1060或洛谷1131 [ZJOI2007]时态同步
BZOJ原题链接 洛谷原题链接 看上去就觉得是一道树形\(\mathtt{DP}\),不过到头来我发现我写了一个贪心.. 显然对越靠近根(记为\(r\))的边进行加权贡献越大,且同步的时间显然是从根到 ...
- java之spring mvc之Restful风格开发及相关的配置
1. Restful : 表征状态状态转移. 传统 : url : http://localhost:8080/usersys/delete.do?user.id=12 Restful 风格:url ...
- C# vb .net实现相机视图效果滤镜
在.net中,如何简单快捷地实现Photoshop滤镜组中的相机视图效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第 ...
- Postman中添加真实请求(Chrome Networks中的全部请求,含https)copy as har
Postman中添加真实请求(Chrome Networks中的全部请求,含https) xyxzfj 关注 2018.05.22 19:44* 字数 559 阅读 1176评论 0喜欢 0 Post ...
- ASP.NET SignalR 系列(二)之项目创建
一.项目环境 IDE:VisualStudio 2015 SignalR 2.3.0 JQuery版本1.10.1 ,要求必须1.6.4以上 .net Framework 4.6 SignalR2.0 ...
- 最全的 pip 使用指南,50% 你可能没用过
所有的 Python 开发者都清楚,Python 之所以如此受欢迎,能够在众多高级语言中,脱颖而出,除了语法简单,上手容易之外,更多还要归功于 Python 生态的完备,有数以万计的 Python 爱 ...
- Vue学习之webpack中使用vue(十七)
一.包的查找规则: 1.在项目根目录中找有没有 node_modules 的文件夹: 2.在 node_modules 中根据包名,找对应的vue 文件夹: 3.在vue 文件夹中,找 一个叫做 pa ...
- java实现在线预览--poi实现word、excel、ppt转html
java实现在线预览 - -之poi实现word.excel.ppt转html 简介 java实现在线预览功能是一个大家在工作中也许会遇到的需求,如果公司有钱,直接使用付费的第三方软件或者云在线预览服 ...