java string 最大长度是多少_字符串String的最大长度

ac07d80e1cbed4c6b24a2e308b6905cd.png

开篇三个问题

作为Java的程序员,不知道在Java代码中定义了多少个字符串,可是看看下面3个问题。你是否认真思考过?是否动手实践过?

1.Java中的字符串String的最大长度是多少?

2.Eclipse使用哪种Java编译器?

3.为何Eclipse要出自己的编译器?

对于字符串可以承受的最大长度,要分为2个阶段,一个是编译时期(也就是你代码定义了一个String字符串,String s= "xiaohu"),一个是运行时期(指在程序运行过程中)

编译期String字符串的限制

我们都知道JVM里面是包含常量池的,(是一种对字符串的性能优化,不用反复创建新的字符串了)当我们使用字符串字面量直接定义String的时候,是会把字符串在常量池中存储一份的。常量池中的每一项常量都是一个表,都有自己对应的类型。Java中的UTF-8编码的Unicode字符串在常量池中以CONSTANT_Utf8_info类型表,结构如下:

CONSTANT_Utf8_info型常量的结构

类型

名称

数量

u1

tag

1

u2

length

1

u1

bytes

length

u2类型的length的值就表明了这个UTF-8编码字符串长度是多少字节。所以CONSTANT_Utf8_info型常量对应的最大长度也就是java中UTF-8编码的字符串的长度,顺便提一下Class文件中的方法和字段也是引用CONSTANT_Utf8_info型常量来描述名称的。u2是无符号的16位整数,因此理论上允许的的最大长度是2^16-1=65535

编译器javac下String的长度

创建一个测试类

public class TestStr {

public static void main(String[] args) {

String LongStr ="aaaa..."//一共65535个a

System.out.println(LongStr.length());

}

}

使用javac命令编译它。编译报错。相应目录没有生成对应的TestStr.class文件

去除一个字符串,使用65534个字符串。

public class TestStr {

public static void main(String[] args) {

String LongStr ="aaaa..."//一共65534个a

System.out.println(LongStr.length());

}

}

javac命令编译它。编译正常。相应目录生成对应的TestStr.class文件

我们在看看Oracle JDK的编译工具Javac内部,javac也是java写的。

/** 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++;

}

...

在看看Pool.MAX_STRING_LENGTH

public class Pool {

...

public static final int MAX_STRING_LENGTH = 0xFFFF;

...

}

通过上边代码可以看到 MAX_STRING_LENGTH = 0xFFFF 而 0xFFFF 是十进制的 65535。但是上面我们得出的结果是Javac编译下最大长度是65534,是因为 Javac 源码中做的限制是((String)constValue).length() < Pool.MAX_STRING_LENGTH) 注意是 < 而不是 <= , 小于65535那自然最多只能是65534了。

但是U2类型能表达的最大值是65535。上面65535个长度的字符串在javac下报错了是受到了javac编译器的限制了。如果你在上面65534长度生成的TestStr.class中手动在添加一个字符串(注意是在javac编译后的class文件中添加)是可以得到65535长度的结果。

总结一下:在Javac编译器下,字符串String的最大长度限制也即是U2类型所能表达的最大长度65534。避开javac最大长度是65535?

Eclise的JDT编译器下String的长度

Eclipse有自己的Java编译器,称为[JDT Core] [2](org.eclipse.jdt.core)。并不是用的javac编译器。

创建一个测试类

public class TestStr {

public static void main(String[] args) {

String LongStr ="aaaa..."//一共65540个a

System.out.println(LongStr.length());

}

}

发现Eclipse执行可正常执行。这肯定是Eclise的JDT编译器做了手脚。果然通过在Eclipse工作空间下找到了其编译生成的TestStr.class。使用javap命令查看

6: invokespecial #20; //Method java/lang/StringBuilder."":(Ljava/la

ng/String;)V

9: ldc #23; //String QyNDAbAgIGqQIBAQ1

11: invokevirtual #25; //Method java/lang/StringBuilder.append:(Ljava/lang

/String;)Ljava/lang/StringBuilder;

14: invokevirtual #29; //Method java/lang/StringBuilder.toString:()Ljava/l

ang/String;

17: invokevirtual #33; //Method java/lang/String.intern:()Ljava/lang/Strin

g;

20: astore_1

21: getstatic #38; //Field java/lang/System.out:Ljava/io/PrintStream;

24: aload_1

25: invokevirtual #44; //Method java/lang/String.length:()I

28: invokevirtual #48; //Method java/io/PrintStream.println:(I)V

31: return

}

上面我们就明白了之所以JDT能编译过,只是因为JDT优化为了StringBuilder的append。

Eclipse编译器本身包含在org.eclipse.jdt.core插件中。Eclipse不会使用任何用户安装的JDK。相反,由于以下主要原因,它使用自己的JDT核心来编译Java程序:

主要原因是JDT核心具有渐进式编译的能力,这意味着它会逐步编译代码中的更改(这也是Eclipse不需要编译按钮的原因,因为它会在检测到更改时自动编译)。但Oracle的JDK不支持增量编译。

运行期String的字符串限制

String内部是以char数组的形式存储,数组的长度是int类型,那么String允许的最大长度就是Integer.MAX_VALUE了。又由于java中的字符是以16位存储的,因此大概需要4GB的内存才能存储最大长度的字符串。

总结一下

1.Java中的字符串String最大长度,编译期如果是javac编译就是65534。如果绕过javac编译的限制,其最大长度可以达到u2类型变达的最大值65535。

2.Java中的字符串String最大长度运行期大约4G。

3.Eclise编译超过65534长度的字符串不报错,是Eclipse有自己的Java编译器。JDT优化为了StringBuilder的append。

4.Eclise使用自己的编译器。主要原因是JDT核心具有渐进式编译的能力,这意味着它会逐步编译代码中的更改(这也是Eclipse不需要编译按钮的原因,因为它会在检测到更改时自动编译)。但Oracle的JDK不支持增量编译。

若本文对你有用,有任何疑问,欢迎关注我。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java中的String类是用于表示字符串的类,它包含许多常用的方法来处理字符串,以下是一些常用的字符串方法及其返回值: 1. length()方法:返回字符串长度,即包含的字符数。 2. charAt(int index)方法:返回字符串中指定位置的字符。 3. substring(int beginIndex, int endIndex)方法:返回从指定位置开始到指定位置结束的子字符串,其中beginIndex表示开始位置(包含),endIndex表示结束位置(不包含)。 4. indexOf(char ch)方法:返回指定字符在字符串中第一次出现的位置,如果不存在则返回-1。 5. indexOf(String str)方法:返回指定字符串字符串中第一次出现的位置,如果不存在则返回-1。 6. replace(char oldChar, char newChar)方法:用指定的新字符替换字符串中所有的旧字符,并返回替换后的新字符串。 7. replaceAll(String regex, String replacement)方法:用指定的新字符串替换字符串中符合正则表达式的所有子串,并返回替换后的新字符串。 8. toUpperCase()方法:将字符串中的所有字母转换为大写字母,并返回新字符串。 9. toLowerCase()方法:将字符串中的所有字母转换为小写字母,并返回新字符串。 10. trim()方法:去除字符串两端的空格,并返回新字符串。 以上这些方法是String类中常用的一些字符串方法,能够满足大多数字符串操作的需求。 ### 回答2: Java中的String类是非常重要的一个类,常用于存储和操作字符串,其中字符串长度是一个基本概念。String类中提供了一些常用方法来获取字符串长度。 1. length()方法:该方法返回一个字符串长度,即字符串中字符的个数。例如: ```java String str = "Hello World!"; int len = str.length(); ``` 上面的代码中,len的值为12,因为字符串中一共有12个字符。 2. isEmpty()方法:该方法返回一个布尔值,判断一个字符串是否为空。如果一个字符串长度为0,则认为它是空的。例如: ```java String str = ""; boolean isEmpty = str.isEmpty(); ``` 上面的代码中,isEmpty的值为true,因为str是一个空字符串。 3. trim()方法:该方法去除字符串两端的空格,并返回去除空格后的字符串。例如: ```java String str = " Hello World! "; str = str.trim(); ``` 上面的代码中,在执行str.trim()方法之后,str的值变为了"Hello World!",去除了两端的空格。 4. getBytes()方法:该方法返回一个字节数组,表示该字符串中每个字符的字节编码。例如: ```java String str = "Hello World!"; byte[] bytes = str.getBytes(); ``` 上面的代码中,bytes的长度为12,因为字符串中一共有12个字符,每个字符占用1个字节。 5. length vs length():需要注意的是,length和length()虽然都可以用来获取字符串长度,但是它们的返回值类型不同。length是一个数组的属性,返回该数组的长度;而length()是String类的方法,返回字符串长度。因此,我们需要根据具体的情况选择使用哪个方法。 在实际开发中,我们会频繁地使用到这些方法,进行字符串长度的计算和判断,从而达到我们想要的程序效果。 ### 回答3: Java中的字符串是一种非常常见的数据类型,可以使用String类来创建和处理字符串。其中,字符串长度String类中的一个非常基本的方法,对于字符串的处理和操作都有着非常重要的意义。 字符串长度可以通过调用String类中的length()方法来获取。该方法返回的是一个整数值,表示该字符串中字符的数量,包括空格和特殊字符。例如,对于下面的字符串String str = "Hello World!"; 调用str.length()方法将返回整数值12,它是该字符串中字符的数量。如果该字符串为空字符串,即“”,那么调用该方法将返回整数值0。 在实际的开发中,字符串长度的获取非常常见,比如在字符串的截取、比较、连接等操作中都需要用到字符串长度。另外,在一些具有字符个数限制的场景中(如数据库中的字段),该方法也可以用来判断字符串长度是否符合规定。 除了length()方法,还有一个类似的属性可以获取字符串长度,就是String类中的length属性。该属性是一个final类型的整数,通过直接访问该属性可以获取字符串长度。例如: String str = "Hello World!"; int len = str.length; 调用str.length将返回整数值12,它等价于调用str.length()方法。不过,需要注意的是,该属性是final类型的,即一旦获取了长度值,就不能再修改了。 因此,对于字符串的操作和处理中,获取字符串长度是一项非常基本的操作。Java中提供了String类中的length()方法和length属性来获取字符串长度,能够满足我们大部分的需求。对于需要频繁使用的场景,也可以将获取到的长度值存储在变量中,以便下次使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值