android string参数最大长度,每日一问 | 我们经常用的 String类型,你知道它最大可以放多长的字符串吗?...

String被用作常量时,它被编译器当成字面量存放于常量池。常量池中主要存放两大类常量:字面量和符号引用;常量池中的每一个常量都是一个表,字符串常量存于CONSTANT_Utf8_info表(Tip:字节码文件由无符号数和表映射的数据构成,详见java虚拟机规范或者周志明老师的深入理解Java虚拟机)。

CONSTANT_Utf8_info {

u1 tag;

u2 length;

u1 bytes[length];

}

CONSTANT_Utf8_info表由tag、length和bytes组成。tag用于标识表的类型,大小为一个字节的无符号数;length表示使用utf-8缩略编码表示的字符串长度,大小为两个字节的无符号数;bytes存放被编码的字符串。字符串常量的最大值为2^16-1(65535)字节。当使用javac编译Test.java文件时,由于其中的字符串长度为65535,超出javac中规定的大小,编译失败;下面是含长度为65534的字符串的Test类编译前后的内容,位于0x7E~0x1007E(包括起止的两个字节)之间的数据为一个CONSTANT_Utf8_info表的映射,tag值为0x01(位于0x7E),之后的两个字节表示length值为0xFFFE(65534),随后的65534个字节字符串内容。

public class Test{

//65534个a

String str="aaaa...";

}

//字节码内容

Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000: CA FE BA BE 00 00 00 34 00 13 0A 00 05 00 0E 08 J~:>...4........

00000010: 00 0F 09 00 04 00 10 07 00 11 07 00 12 01 00 03 ................

00000020: 73 74 72 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 str...Ljava/lang

00000030: 2F 53 74 72 69 6E 67 3B 01 00 06 3C 69 6E 69 74 /String;...

00000040: 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 >...()V...Code..

00000050: 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 .LineNumberTable

00000060: 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 ...SourceFile...

00000070: 54 65 73 74 2E 6A 61 76 61 0C 00 08 00 09 01 FF Test.java.......

00000080: FE 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 ~aaaaaaaaaaaaaaa

...

00010070: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 0C aaaaaaaaaaaaaaa.

00010080: 00 06 00 07 01 00 04 54 65 73 74 01 00 10 6A 61 .......Test...ja

00010090: 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 00 21 va/lang/Object.!

000100a0: 00 04 00 05 00 00 00 01 00 00 00 06 00 07 00 00 ................

000100b0: 00 01 00 01 00 08 00 09 00 01 00 0A 00 00 00 27 ...............'

000100c0: 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 12 02 B5 ........*7..*..5

000100d0: 00 03 B1 00 00 00 01 00 0B 00 00 00 0A 00 02 00 ..1.............

000100e0: 00 00 01 00 04 00 02 00 01 00 0C 00 00 00 02 00 ................

000100f0: 0D

javac无法编译字符串常量长度超过65534的java文件

原因:javac中对字符串常量长度做了限制,可以下面的checkStringConstant方法中看出。(Tip:javac源码位于OpenJDK中,并且各个版本路径不一定相同,修改上面的字节码文件,将length值由0xFFFE改为0xFFFF,并将bytes数据添加一个字节,执行java命令,程序正常运行。)

//位于javac源码中的Gen.java文件,Errors.LimitString 为constant string too long

//Pool.MAX_STRING_LENGTH值为0xFFFF

/** Check a constant value and report if it is a string that is

* too large.

*/

private void checkStringConstant(DiagnosticPosition pos, Object constValue) {

if (nerrs != 0 || // only complain about a long string once

constValue == null ||

!(constValue instanceof String) ||

((String)constValue).length() < Pool.MAX_STRING_LENGTH)

return;

log.error(pos, "limit.string");

nerrs++;

}

String被当作变量时,其长度由String存储方式决定。在JAVA SE 9之前,String内部是由char数组存储的,数组最大长度为Integer.MAX_VALUE(0x7fffffff),即2^31-1,并且char的取值范围在0~65535之间,占两个字节,因此String的最大长度为429496967294字节,运行时需要大约4GB的内存才能存储;JAVA SE 9及其后续版本将char数组改为byte数组,因此String的最大长度为2147483647字节。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值