
据说string存放字符串的格式为,首位为全串的长度,后边才是真正的字符串。即首位s[0]存放了字符串的长度。
所以pascal中有ord(s[0])等于字符串长度的说法,但是经过测试,在Delphi中这样实现不了,只能通过length(s)获得。
两个字符串的比较规则为,从左到右按照ASCⅡ码值逐个比较,遇到ASCⅡ码不等时,规定ASCⅡ码值大的字符所在的字符串为大。
例如:'AB'<'AC' 结果为真;
'12'<'2' 结果为真;
'PASCAL '='PASCAL' 结果为假;
---------------------------------------
string[n], n是定义的字符串长度,必须是0~255之间的自然整数,第0号单元中存放串的实际长度,程序运行时由系统自动提供,第1~n号单元中存放串的字符。若将string[n]写成string,则默认n值为255。
copy(s,m,n) 取s中第m个字符开始的n个字符 若m大于s的长度,则返回空串;否则,若m+n大于s的长度,则截断
length(s) 求s的动态的长度 返回值为整数
pos(sub,s) 在s中找子串sub 返回值为sub在s中的位置,为byte型
insert(sour,s,m) 在s的第m个字符位置处插入子串sour 若返回串超过255,则截断
delete(s,m,n) 删除s中第m个字符开始的n个字符串 若m大于s的长度,则不删除;否则,若m+n大于s的长度,则删除到结尾
初看到这个问题心里还是有点尴尬的,平时确实没注意过String最大能有多长。想要知道String到底有多长,只能从源码层面来找答案了。
Java中String不是基本数据类型,而是引用类型并且是final。String定义为final的原因:
高效性
JVM在查找字符串的时候可以直接定位到String类中,更准确的说String不可变,才能实现常量池。
安全性
定义成final,不能被继承和修改,可以防止在子类或者其他地方被修改,导致隐藏Bug产生。
上面提到常量池,JVM创建对象是需要开销的,为了提高性能,对字符串使用字符串常量池进行了优化,每当我们创建一个字符串时,Jvm先去字符串常量池检查,如果字符串常量池存在,直接返回实例引用;否则创建实例,并存入字符串常量池中。
比如常见的判断:
因为a和b都是指向"hello"这个常量池中的常量,即同一个地址所以a==b 为true
因为c是new了一个新对象,且对象是在堆上存放,所以c==a为false,虽然c的内容是创建在堆中,但是他的内部value还是指向JVM常量池的hello的value,它构造hello时所用的参数依然是hello字符串常量。
下面正式进入今天的主题了,String的最大长度到底是多大呢?
翻开String类的源码,你会看到:
可以看到String的length是通过count值返回的,count是int型,最大为2 31 -1,所以String理论上最大长度为2 31 -1,2147483647。
但是由于String底层是通过char[]字符数组来实现,char占用两个字节,2147483647 个 char 类型就是 4294967294 字节,这接近于 4GB 大小,想要申请这么一大块连续的内存空间,失败也就不足为奇了,所以和电脑的硬件条件有关。
总结
String 的最大长度也就是字符数组的最大长度,理论上最大长度为 int 类型的最大值,即 2147483647。
在实际中,一般可获取的最大值小于理论最大值。
u2是无符号的16位整数,因此理论上允许的string literal的最大长度是2^16-1=65535。然而实际测试表明,允许的最大长度仅为65534,超过就编译错误了,有兴趣可以写段代码试试,估计是length还不能为0。欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)