网站首页 > java教程 正文
关于String到底有没有长度限制,相信在实际开发中,很多开发者都遇到过处理超长字符串的问题。下面我们就来结合Java原理来分析关于String类型长度限制。
String类型的长度
笔者就遇到这样一个问题,将一个超大的字符串使用String类型进行处理,然后点运行程序之后,就会报错。这到底是为什么呢?
在String类型中,有一个如下的构造函数。
public String(byte bytes[], int offset, int length)
这个构造函数中,传入了一个字符串的长度,并且数据类型是int类型,也就是说传入的字符串长度最大支持的长度应该是int的表数范围。也就是2的31次方减一。是不是String类型的长度真的就是这个长度呢?在笔者操作数据的时候,数据长度明显要比这个长度要小,但是还是报错了?也就是说笔者在编译的时候就报错了。
也就是说这里的长度只是支持的理论值,也就是在运行的时候支持的大小,但是在实际编译的时候字符串的长度是有限制的。
String s = "11111...1111";//其中有10万个字符"1"
这个时候会有人问?既然支持的构造方法长度达到2147483647(2^31 - 1)长度了,那么为什么不能编译呢?
常量池的限制
在介绍JVM的时候,我们知道Java程序执行首先要通过编译操作生成一个class文件,但是在这个Class文件生成过程中会遵守一些规则,这个规则被称为是虚拟机规范。那么在虚拟机规范中就对String类型的长度进行了规定。
而所谓的规定就是String类型作为字符串所能表示的大小范围,我们知道,在世界上有很多的字符集,并且这些字符都有自己的字符集编码例如UTF-8、GBK、Unicode等等。而在Java底层所支持的就是Unicode编码,这种编码最终就被转换成一个String字符串。而在这个操作过程中,需要遵循的就是Unicode编码规范大小,也就是65535个长度。
也就是说在Class文件中对于常量池的规定就是不能超过65535。
那么我们将上面的测试代码改成
String s = "11111...1111";//65535字符"1"
这个时候还是会报错。这个是什么原因呢?
这个是因为,在我们操作字符串编译常量池的时候,大于或者等于65535的时候都会报错。这个现象,大家可以通过Debug操作来追踪相关的内容。
运行时限制
在上面我们提到了在编译阶段的限制,并且介绍了理论运行阶段的值限制,那么在运行阶段String的长度有什么限制呢?
在上面我们介绍了最大的长度应该是4G,也就是是Integer的表数范围,如果当一个字符串超过这个大小的时候也会报错。
这个时候有人就会疑惑为什么在编译的时候是65535而运行的时候就可以超过这个限制呢?
其实这个是很常见的的,在编译的时候有很多的规则检查,但是通过了这些规则检查之后,在运行阶段就需要更多的内存支持,例如将一个图片转换成BASE64字符进行存储,在编译的时候我们只需要定义一个变量准备接受这个字符串就行了,在实际使用的时候才能知道这个字符串里面到底能够存储多少字符。
总结
从上面的分析可以知道,字符串的大小是有限制的,在编译阶段遵守的是虚拟机规范,而在运行阶段则是不能超过Int的表数范围。
- 上一篇: Python教程:第17篇 比较运算符
- 下一篇: Java 中的 String Pool 简介
猜你喜欢
- 2024-11-27 正确理解和使用JAVA中的字符串常量池
- 2024-11-27 面试Java岗 Integer和String必问知识点,你必须精通
- 2024-11-27 JAVA基础&String&StringBuffered&StringBuilder
- 2024-11-27 Java 17 I/O StringWriter 篇
- 2024-11-27 高端面试必备:一个Java对象占用多大内存?
- 2024-11-27 Java基础类String学习分析
- 2024-11-27 懵了!面试官问我:String 长度有限制吗?是多少?
- 2024-11-27 扒开外衣仔细分析:String为什么不可变
- 2024-11-27 对象的内存布局,怎样确定对象的大小
- 2024-11-27 「Java技术探索」带你进入String类的易错点和底层本质分析
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)