java string 多长_String类型到底有多长

2023-05-16

最近做项目遇到一个问题,服务商给我们传递数据的时候会将参数信息加密,奇怪的是我代码解密可以通过,因为测试解密方法,我手动解析的一下参数(因为等解码完成,我服务端的程序已经判断超时了,所以为了看返回的数据手动调的),结果提示常量字符串过长,那么String有没有长度限制的问题。

28cdbe532d740f03beebdc93ef94ea26.png

猜测:因为运行的时候可以通过,而手动编译的时候确提示常量字符串过长,所以运行是字符串长度是不是没有限制,而编译的时候会有限制呢???

我们先看下字符串的源码有没有定义字符串的长度。

可以看到String类中有很多重载的构造函数。

a552d780160e6191da70b690eb147ccc.png

找找看有可以支持用户传入长度的方法。

65aacebac32694b7579a1c80af7fbdf1.png

长度是int那么他的长度是否就是int max=2147483647;

验证猜想:

fb521fcd6227933fce2de574b5f8f4b8.png

80bed97ab9d35c0e56a032bfb7e31b13.png

运行的时候长度一万十万的都打印出来了,一百万的没有打印出来虽然但是猜测是内存溢出了,毕竟这么拼接字符串(内存溢出只是猜测没有验证)

a4942b96e5ca71d892cc8af7ff5d1a76.png

7bfec307f4fe8bc641dfc6ac3b745b53.png

长度一万正常但是长度为十万时!!!!

1a4d50c3870cc286184d0c6f00338b86.png

看来我的猜测是对的,运行的时候就算字符串长度超过十万也能运行,但是当字符串长度等于十万时就会报常量字符串过长,而且字符串长度可以传int的,为什么才十万就报错了???

Javac再编译时String s = "xxx";定义String的时候,xxx被我们称之为字面量,这种字面量在编译之后会以常量的形式进入到Class常量池。

String内部是以百char数组的形式存储,数组的长度是int类型,那么String允许的最大长度就是Integer.MAX_VALUE了。又由于java中的字符是以16位存储的,因此大概需要4GB的内存才能存储最大长度的字符串度。专不过这仅仅是对字符串变量而言,如果是字符串字面量(string literals),如“abc"、"1a2b"之类写在代码中的字符串literals,那么允许的最属大长度取决于字符串在常量池中的存储大小,也就是字符串在class格式文件中的存储格式:

CONSTANT_Utf8_info {

u1 tag;

u2 length;

u1 bytes[length];

}

u2是无符号的16位整数,因此理论上允许的string literal的最大长度是2^16-1=65535。然而实际测试表明,允许的最大长度仅为65534,超过就编译错误了,这里在javac的代码中有定义代码中可以看出,当参数类型为String,并且长度大于等于65535的时候,就会导致编译失败。

private voidcheckStringConstant(DiagnosticPosition var1, Object var2) {

if(this.nerrs == 0 && var2 != null&& var2 instanceofString

&& ((String)var2).length() >= 65535) {

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

++this.nerrs;

}

}

713fa5a8ab14b22898529d826fcf5acb.png

8b0850fdba4ff4745f483bc0c6ff8c16.png

而要测试运行时,String的长度大小能否超过4G可以通过base64加密文件试试。

总结:String的长度是有限制的编译时长度在常量池中定义(String str = "ii"会编译成常量),运行时长度可以达到int的最大值,大概4G左右。路过的大佬有看到错误希望给小弟指出,感激不尽。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java string 多长_String类型到底有多长 的相关文章

随机推荐