在学习和开发过程中,我们经常会讨论 short ,int 和 long 这些基本数据类型的取值范围,但是对于 String 类型我们好像很少注意它的“取值范围”。那么对于 String 类型,它到底有没有长度限制呢?

其实 String 类型的对象,他们是有长度限制的, String 对象并不能“存储”无限长度的字符串。关于 String 的长度限制要从编译时限制和运行时限制两方面考虑。

编译期限制

有JVM虚拟机相关知识的同学肯定知道,下面定义的字符串常量“自由之路”会被放入方法区的常量池中。

String s = "自由之路";

System.out.println(s);

Stirng 长度之所以会受限制,是因JVM规范对常量池有所限制。常量池中的每一种数据项都有自己的类型。Java中的UTF-8编码的Unicode字符串在常量池中以CONSTANT_Utf8类型表示。

CONSTANT_Utf8的数据结构如下:

CONSTANT_Utf8_info {

u1 tag;

u2 length;

u1 bytes[length];

}

我们重点关注下长度为 length 的那个bytes数组,这个数组就是真正存储常量数据的地方,而 length 就是数组可以存储的最大字节数。length 的类型是u2,u2是无符号的16位整数,因此理论上允许的的最大长度是2^16-1=65535。所以上面byte数组的最大长度可以是65535。

//65535个d,编译报错

String s = "dd..dd";

//65534个d,编译通过

String s1 = "dd..d";

上面的列子中长度为65535的字符串s还是编译失败了,但是长度为65534的字符串 s1 编译是成功的。这个好像和我们刚刚的结论不符合。

其实,这时Javac编译器的额外限制。在Javac的源代码中可以找到以下代码:

private void checkStringConstant(DiagnosticPosition var1, Object var2) {

if (this.nerrs == 0 && var2 != null && var2 instanceof String && ((String)var2).length() >= 65535) {

this.log.error(var1, "limit.string", new Object[0]);

++this.nerrs;

}

}

代码中可以看出,当参数类型为String,并且长度大于等于65535的时候,就会导致编译失败。

这里需要重点强调下的是:String 的限制并不是对字符串长度的限制,而是对字符串底层存储的限制。这句话可能比较抽象,下面举个列子就清楚了。

Java中的字符常量都是使用UTF8编码的,UTF8编码使用1~4个字节来表示具体的Unicode字符。所以有的字符占用一个字节,而我们平时所用的大部分中文都需要3个字节来存储。

//65534个字母,编译通过

String s1 = "dd..d";

//21845个中文”自“,编译通过

String s2 = "自自...自";

//一个英文字母d加上21845个中文”自“,编译失败

String s3 = "d自自...自";

对于s1,一个字母d的UTF8编码占用一个字节,65534字母占用65534个字节,长度是65534,也没超过Javac的限制,所以可以编译通过。

对于s2,一个中文占用3个字节,21845个正好占用65535个字节,而且字符串长度是21845,并没有超过javac对长度的限制,所以可以编译通过。

对于s3,一个英文字母d加上21845个中文”自“占用65536个字节,超过了最常限制,编译失败。

运行时限制

String 运行时的限制主要体现在 String 的构造函数上。下面是 String 的一个构造函数:

public String(char value[], int offset, int count) {

...

}

上面的count值就是字符串的最大长度。在Java中,int的最大长度是2^31-1。所以在运行时,String 的最大长度是2^31-1。

但是这个也是理论上的长度,实际的长度还要看你JVM的内存。我们来看下,最大的字符串会占用多大的内存。

(2^31-1)*2*16/8/1024/1024/1024 = 4GB

所以在最坏的情况下,一个最大的字符串要占用4GB的内存。如果你的虚拟机不能分配这么多内存的话,会直接报错的。

JDK9以后对String的存储进行了优化。底层不再使用char数组存储字符串,而是使用byte数组。对于LATIN1字符的字符串可以节省一倍的内存空间。

简单总结

String 的长度是有限制的。

编译期的限制:字符串的UTF8编码值的字节数不能超过65535,字符串的长度不能超过65534;

运行时限制:字符串的长度不能超过2^31-1,占用的内存数不能超过虚拟机能够提供的最大值。

公众号推荐

欢迎大家关注我的微信公众号「程序员自由之路」

java string 最大长度是多少_String字符串的最大长度是多少?相关推荐

  1. 画图说明Java String的不变性!可修改字符串不要轻易使用String!

    这里用一组图表来说明Java字符串的不可变性. 1. 声明一个字符串 以下代码初始化字符串s 变量s存储字符串对象的引用,如下所示.箭头可以解释为"存储的引用". 2. 将一个字符 ...

  2. java string能存储多长_String 有多长?

    1 String的形式public final class String String类是由final修饰的,所以是不能被继承的①,我们在对字符串进行比较时,一般是期望对比其中的字符串是否一样,所以这 ...

  3. JAVA中获得一个有中文的字符串的字节长度

    http://houfei90.blog.163.com/blog/static/169255221201182234456375/ 由于Java是基于Unicode编码的,因此,一个汉字的长度为1, ...

  4. java string 字符个数字_java从字符串中提取数字

    string类函数的补充说明: trim()方法返回调用字符串对象的一个副本,但是所有起始和结尾的空格都被删除了,例子如下:String s=" Hello World ".tri ...

  5. leetcode 1239. Maximum Length of a Concatenated String with Unique Characters | 1239. 串联字符串的最大长度(回溯)

    题目 https://leetcode.com/problems/contiguous-array/ 题解 回溯法,每个字符串都有可能加或者不加. class Solution {int N;publ ...

  6. linux文件名的长度不能超过个字符串,文件名的长度可达()个字符

    [单选] 文件名的长度可达()个字符. A . 1 B . 无数 C . 255 D . 10 文件名的长度可长达255个字符. 为了方便人们区分计算机中的不同文件,而给每个文件设定一个指定的名称.由 ...

  7. Java String API 常用的String方法详解

    标题 String类的特性 Java中String类的构造方法 String类的 intern() 注意还跟jdk有关 如何保证变量S指向的是字符串常量池中的数据呢? 关于String中 new St ...

  8. java string join 用法_Java String join() 使用方法及示例

    Java String join() 使用方法及示例 Java String join()方法返回一个新字符串,该字符串具有给定的元素和指定的分隔符. 字符串join()方法的语法为: String. ...

  9. Java String equalsIgnoreCase()方法的功能说明

    转自: Java String equalsIgnoreCase()方法具有什么功能呢? Java String equalsIgnoreCase()方法的功能说明 Java String equal ...

最新文章

  1. 【网友的】《一个程序猿的生命周期》读后感
  2. 用C++对C++语法格式进行分析
  3. TCP/IP原理 (一)
  4. sklearn提取图片信息
  5. iOS使用NSMutableAttributedString实现富文本
  6. iCMS v8.0.0多终端内容管理系统
  7. 手写一个promise用法_手写一个自己的 JavaScript Promise 类库
  8. 法国PSA集团宣布,2018年就推出自动驾驶技术
  9. MongoDB如何释放空闲空间?
  10. 安装LoadRunner 11时弹窗提示Micosoft Visual C++ 2005 SP1 可再发行组件包(X86):'命令行选项语法错误。键入命令 / ? 可获得帮助信息'。
  11. 拓端tecdat|R语言最优化问题中的共轭函数
  12. mysql无法远程连接 111_如何解决远程连接mysql出现Can't connect to MySQL server on (111 Connection refused)的问题...
  13. 手机应用误删怎么恢复
  14. Android开发 之 OpenGL ES系列(5--3D立体图形)
  15. 使用短信登录和注册的流程
  16. cf #818 Div.2(A~C)
  17. 微信小程序用什么编写
  18. html怎么查看cad文件,怎么将电脑CAD文件在手机上查看?原来怎么简单!
  19. 前端实现文件上传的断点续传
  20. 动态规划解决小青蛙跳台阶问题

热门文章

  1. Android S系统启动流程
  2. buu [MRCTF2020]keyboard
  3. 深度优先搜索的概念原理、模板和leetcode刷题推荐(js)
  4. Ubuntu镜像源更改为清华镜像源
  5. 推荐三个我一直关注的原创公众号
  6. 怎么在动态表情包上添加文字,gif添加文字
  7. 应用于交直流配电网的电力电子变压器(学习笔记)
  8. 五万块钱买什么车好_5万左右买什么车好?选这4款没错
  9. 假如你是只猫,那一定也很可爱很帅!是只酷酷的猫!
  10. 教育数字化时代,远程控制软件TeamViewer大显身手