开篇三个问题

作为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不支持增量编译。

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

java string 最大长度是多少_字符串String的最大长度相关推荐

  1. python字符串最大长度_字符串String的最大长度

    开篇三个问题 作为Java的程序员,不知道在Java代码中定义了多少个字符串,可是看看下面3个问题.你是否认真思考过?是否动手实践过? 1.Java中的字符串String的最大长度是多少? 2.Ecl ...

  2. java获取字符串长度_java中定义字符串String s=”pzhu”,下面操作可以取得字符串长度的是( )。...

    [单选] 施工现场宿舍.办公室等临时用房建筑构件的燃烧性能等级应为():当采用金属夹芯板材时,其芯材的燃烧性能等级应为(). [填空题] <敦煌曲谱>又名(),是933年用燕乐半字谱抄写的 ...

  3. java自动转换需要的开头_字符串和数值型进行运算时,字符串如果不是数字开头,会自动转换成什么?...

    [单选题]下列哪个不属于氯丙嗪用于人工冬眠疗法的适应证 [单选题]某流域有甲.乙两个雨量站,它们的权重分别为0.4,0.6,已测到某次降水量,甲为80.0mm,乙为50.0mm,用泰森多边形法计算该流 ...

  4. 给一个长度为n的字符串,找出长度为m的最小字典子序列【单调栈】

    一个大大的分割线,如果这个傻逼题没有被作为某某复赛的签到题,可能我一会都一直傻逼下去了. [2019计蒜之道复赛--星云系统] 题目是,给出一个长度为n(1<n<5e6)的只有小写字母的字 ...

  5. mysql 一行数据长度限制吗_【MySQL】行长度的一些限制

    标签: 今天开发在导入数据的时候报一个错误: Row size too large. The maximum row size for the used table type, not countin ...

  6. 【Java】字符串String操作

    Java中的字符采用Unicode编码.Java SE提供了三个字符串类:String,StringBuffer,StringBuilder.String是不可变字符串,StringBuffer和St ...

  7. java char数组转string数组_Java中char数组(字符数组)与字符串String类型的转换方法...

    本文实例讲述了Java中char数组(字符数组)与字符串String类型的转换方法.分享给大家供大家参考,具体如下: 在Java语言编程时,使用"口令字段"jPasswordFie ...

  8. 【C++ 语言】C++字符串 ( string 类 | 创建方法 | 控制台输出 | 字符串操作 | 栈内存字符串对象 | string* )

    文章目录 C++ 字符串 对象 C++ 字符串 对象 创建方法 C++ 字符串 对象 输出到控制台 C++ 字符串 拼接 C++ 字符串 方法调用 ( 栈内存对象 ) C++ 字符串 方法调用 ( 堆 ...

  9. java string对象名称_java中常见对象——String

    字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. A:字符串字面值"abc"也可以看成是一个字符串对象. B:字符串是常量,一旦被赋值,就不能被改变. 构造方法: ...

最新文章

  1. mysql主从切换机制torch_Mysql主从复制 - osc_y0vjyklt的个人空间 - OSCHINA - 中文开源技术交流社区...
  2. iOS开发debug集锦
  3. ppt讲解中的过渡_PPT教程:缩放定位功能详解
  4. 文巾解题 198. 打家劫舍
  5. (飞鸽传书绿色版)网站
  6. 【Cocos2d-X开发学习笔记】第05期:渲染框架之布景层类(CCLayer)的使用
  7. 数据结构笔记(三)-- 链式实现顺序表
  8. pytorch实现人脸识别_PyTorch实现,GitHub4000星:微软开源的CV库
  9. sikuli python java_自动化测试之sikuli调研
  10. 类似QQ表情的控件 EmotionContainer(原创)
  11. autoCAD 使用图层、颜色和线型
  12. defineExpose暴露
  13. 微服务架构 VS 单体架构
  14. 制作自己的刷机shx文件
  15. 微信开放平台-管理中心-应用删除
  16. Java通过jacob生成动态word,还有一种方法通过word书签实现
  17. 微信开发获取地理位置实例(java,非常详细,附工程源码)
  18. matlab闭式网络潮流计算,大工20秋《电力系统分析》在线作业2满分
  19. 小程序云服务器机型选择,小程序云服务器机型选择
  20. SAM9X60 curiosity开发板,U盘拷贝文件到开发板

热门文章

  1. 华清远见—java web后端学习总结
  2. literal在程序語言中的意思(轉)
  3. python3 eval安全替代函数ast.literal_eval的区别
  4. 开卷有益的《开源技术选型手册》
  5. 接入腾讯云识别图片中的文字并保存(数学建模)
  6. 对抗生成网络Gan变体集合 keras版本
  7. 如何在 iPhone、iPad、iPod touch 或 Mac 上,更新 HomePod
  8. 基于某地区高校数据探究大学生健康状态
  9. c++:训练3控制台输出汉字,用cout输出汉字“明日科技”
  10. 持久内存BTT实现及优化(一)