字符串';Java中的最大长度-调用length()方法
在Java中,引用字符串';Java中的最大长度-调用length()方法,java,string,Java,String,在Java中,引用length()方法调用时,字符串对象的最大大小是多少 我知道length()将字符串的大小返回为char[] 由于数组必须用整数索引,因此数组的最大长度为Integer.MAX_INT(231-1或2147483647)。当然,这是假设您有足够的内存来容纳该大小的数组。考虑到类的方法返回一个int,该方法将返回的最大长度为,即2^31-1(约20亿) 就数组的长度和索引而言,(例如char[],这可能是Strings实现内部数据表示的方式),如下所示: 数组中包含的变量 没有
length()
方法调用时,字符串
对象的最大大小是多少
我知道
length()
将字符串的大小返回为char[]
由于数组必须用整数索引,因此数组的最大长度为Integer.MAX_INT
(231-1或2147483647)。当然,这是假设您有足够的内存来容纳该大小的数组。考虑到类的方法返回一个int
,该方法将返回的最大长度为,即2^31-1
(约20亿)
就数组的长度和索引而言,(例如char[]
,这可能是String
s实现内部数据表示的方式),如下所示:
数组中包含的变量
没有名字;相反,他们是
由数组访问表达式引用
使用非负整数索引的
价值观这些变量称为
阵列的组件。如果一个数组
有n
组件,我们说n
是
阵列的长度;组成部分
使用整数引用数组
从0
到n-1
的索引,包括在内
此外,索引必须通过int
值进行,如中所述:
数组必须按int
值进行索引
因此,似乎极限确实是2^31-1
,因为这是非负int
值的最大值
但是,可能还有其他限制,例如数组的最大可分配大小。显然它绑定到一个int,即0x7FFFFFFF(2147483647)。这得出结论,当与DataInput
和DataOutput
一起使用时,字符串的长度受到字符串的修改UTF-8表示的字节数的限制
此外,Java虚拟机规范中定义了如下结构
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
您可以发现“length”的大小为两个字节
特定方法(例如String.length()
)的返回类型为int
并不总是意味着其允许的最大值为Integer.MAX\u值。相反,在大多数情况下,选择int
只是出于性能原因。Java语言规范指出,小于int
的整数在计算之前会转换为int
(如果我的内存没有问题的话),这是在没有特殊原因的情况下选择int
的一个原因
编译时的最大长度最多为65536。请再次注意,长度是表示的字节数,而不是字符串中的字符数
String
对象在运行时可能有更多的字符。但是,如果要将String
对象与DataInput
和DataOutput
接口一起使用,最好避免使用太长的String
对象。当我实现与DataInput.readUTF()
和DataOutput.writeUTF(String)
等价的Objective-C时,我发现了这个限制。String类的length()方法的返回类型是int
公共整数长度()
提及
因此int的最大值是2147483647
字符串在内部被视为字符数组,因此索引是在最大范围内完成的。
这意味着我们无法索引2147483648成员。因此,java中字符串的最大长度为2147483647
在java中,基元数据类型int为4字节(32位)。由于1位(MSB)用作符号位,因此范围限制在-2^31到2^31-1(-2147483648到2147483647)之间。
我们不能使用负值进行索引。因此,我们可以使用的范围显然是从0到2147483647。我有一个2010 iMac,内存为8GB,运行Eclipse Neon.2发行版(4.6.2)和Java 1.8.025。使用VM参数-Xmx6g,我运行了以下代码:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
try {
sb.append('a');
} catch (Throwable e) {
System.out.println(i);
break;
}
}
System.out.println(sb.toString().length());
因此,似乎最大数组大小为~1207959549。然后我意识到,我们实际上并不关心Java是否耗尽了内存:我们只是寻找最大数组大小(它似乎是某个地方定义的常量)。因此:
所以,看起来max是整数。max_值是-2,或者(2^31)-3
另外,我不知道为什么我的StringBuilder
在1207959550
处最大,而我的char[]
在(2^31)-3处最大。似乎AbstractStringBuilder
将其内部char[]
的大小增加了一倍,这样可能会导致问题。如中所述,java以JVM规范的形式表示Unicode字符串,2个字节分配给长度(而不是字符串的字符数)。
为了扩展答案,库的包含以下内容:
public ByteVector putUTF8(最终字符串字符串值){
int charLength=stringValue.length();
如果(字符长度>65535){
//如果字符数>65535,而不是UTF-8编码长度,则无法容纳2个字节。
抛出新的IllegalArgumentException(“UTF8字符串太大”);
}
对于(int i=0;i='\u0001'&&charValue 1byte,则调用encodeUTF8
方法:
final ByteVector encodeUtf8(final String stringValue,final int offset,final int maxByteLength/*=65535*/){
int charLength=stringValue.length();
int byteLength=偏移量;
for(int i=偏移量;iRequested array size exceeds VM limit
1207959550
for (int i = 0; i < 1_000; i++) {
try {
char[] array = new char[Integer.MAX_VALUE - i];
Arrays.fill(array, 'a');
String string = new String(array);
System.out.println(string.length());
} catch (Throwable e) {
System.out.println(e.getMessage());
System.out.println("Last: " + (Integer.MAX_VALUE - i));
System.out.println("Last: " + i);
}
}
Requested array size exceeds VM limit
Last: 2147483647
Last: 0
Requested array size exceeds VM limit
Last: 2147483646
Last: 1
Java heap space
Last: 2147483645
Last: 2