java中的String定义的字面量最大长度是多少

java的String对象底层是有字符数组存储的,理论上char[]  最大长度是int的最大值,实际

思路:

首先,String字面常量是由String类来维护的,并且在编译时就可以确定(具体请参考String常量池)。因而,如果String字面常量存在一个最大的长度(目前暂且假设),而我们使用的字面常量又超过了这个极限,那么,在编译期间,编译器就能够给出错误信息。因此,我们可以使用IO流生成Java文件,文件的内容就是声明一个String对象,然后使用字面常量赋值,根据动态编译结果,调整字面常量的长度,最后得出字面常量的最大长度值

根据以下代码得出结论(代码来自书《Java深入解析:透析Java本质的36个话题 》):

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class LiteralLength {

 public static void main(String[] args) throws Exception {
 String fileName = "D:/Literal.java";
 StringBuilder prefix = new StringBuilder();
 prefix.append("public class Literal{ String s = \"");
 int low = 0;
 int high = 100_0000;
 int mid = (low + high)/2;
 StringBuilder literal = new StringBuilder(high);

 int result;

 String ch = "A";
 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
 //自定义错误输出流 取代System的err
 OutputStream err = new OutputStream() {

  @Override
  public void write(int b) throws IOException {

  }
 };

 int max = 0;
 for (int i = 0; i < mid; i++) {
  literal.append(ch);
 }
 while(low <= high){
  StringBuilder fileContent
        = new StringBuilder(literal.length() + prefix.length() * 2);
  fileContent.append(prefix);
  fileContent.append(literal);
  fileContent.append("\";}");
  FileWriter w = new FileWriter(fileName);
  BufferedWriter bw = new BufferedWriter(w);
  bw.write(fileContent.toString());
  bw.close();
  w.close();//生成java文件
  result = compiler.run(null,null,err,fileName);

  //代码点的数量
  int codePointCount = literal.codePointCount(0,literal.length());
  if(result == 0){//0表示没有编译错误
  low = mid + 1;
  mid = (low + high)/2;
  max = codePointCount;
  for (int i = codePointCount; i < mid; i++) {
   literal.append(ch);
  }
  System.out.println("长度" + max
            + "编译成功,增加长度至" + mid);

  }else{
  //编译错误,说明字面量太长
  high = mid - 1;
  mid = (low + high)/2;
  System.err.println("长度" + codePointCount
            + "编译失败,减少长度至" + mid);
  int start = ch.length() == 1? mid : mid *2;
  literal.delete(start,literal.length());
  }
 }
 err.close();
 System.out.println("最大字面量长度:" + max);

 }
}

输出结果:

长度500000编译失败,减少长度至249999
长度249999编译失败,减少长度至124999
长度124999编译失败,减少长度至62499
长度62499编译成功,增加长度至93749
长度93749编译失败,减少长度至78124
长度78124编译失败,减少长度至70311
长度70311编译失败,减少长度至66405
长度66405编译失败,减少长度至64452
长度64452编译成功,增加长度至65428
长度65428编译成功,增加长度至65916
长度65916编译失败,减少长度至65672
长度65672编译失败,减少长度至65550
长度65550编译失败,减少长度至65489
长度65489编译成功,增加长度至65519
长度65519编译成功,增加长度至65534
长度65534编译成功,增加长度至65542
长度65542编译失败,减少长度至65538
长度65538编译失败,减少长度至65536
长度65536编译失败,减少长度至65535
长度65535编译失败,减少长度至65534
最大字面量长度:65534

但是若 修改代码

String ch = "α";

结论 : 最大字面量长度:32767

若  String ch = "字";

最大字面量长度:21845

在class文件中,使用CONSTANT_Utf8_info表来存放各种常量字符串,包括String字面常量,类或接口的全限定名,方法及变量的名称、描述符等。CONSTANT_Utf8_info表的结构如表 所示。

java中的String定义的字面量最大长度是多少

从表3-1可知,CONSTANT_Utf8_info表使用2字节来表示字符串的长度,因此,bytes数组的最大长度为216−1,即65535字节。可是,为什么4个字符(“A”、“á”、“字”与“㊣”)的运行结果各不相同呢?原因在于,在CONSTANT_Utf8_info表中,从“\u0001”~“\u007f”,bytes使用1字节来表示,空字符(null,即“\u0000”)和从“\u0080”~“\u07ff”,使用2字节来表示,从“\u0800”~“\uffff”,使用3字节来表示,而对于增补字符,即代码点范围在“U+10000”~“U+10FFFF”之间的字符,使用6字节来表示。也可以这样认为,增补字符是使用一个代理对来表示的,而代理对的取值范围为“\ud800”~“\udfff”,这些字符都在“\u0800”~“\uffff”之间,每个代理字符使用3字节表示,共6字节。上述的存储是在class文件中的实现,不要与Java程序中的字符相混淆,对于Java程序来说,“A”、“á”、“字”都使用一个char类型变量表示,即2字节,而“[插图]”(增补字符)使用两个char类型变量表示,即4字节。

java中的String定义的字面量最大长度是多少

String字面常量的最大长度与String在内存中的最大长度是不一样的,后者的最大长度为int类型的最大值,即2147483647,而前者根据字符(字符Unicode值)的不同,最大长度也不同,最大长度为65534(可手动修改class文件,令输出结果为65535)。

String字面常量的最大长度是由CONSTANT_Utf8_info表来决定的,该长度在编译时确定,如果超过了CONSTANT_Utf8_info表bytes数组所能表示的上限,就会产生编译错误。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 连接 连接池产生原因 连接池实现原理 小结 TEMPERANCE:Eat not to dullness;drink not to elevation.节制
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。-- 毕玄 1. 命名风格 【书摘】类名用 UpperCamelC
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个人在用”。哪怕只是throw了一个新的Exception。哈哈,这是我犯的错误。一、接口和抽象类类,即一个对象。先抽象类,就是抽象出类的基础部分,即抽象基类(抽象类)。官方定义让人费解,但是记忆方法是也不错的 —包含抽象方法的类叫做抽象类。接口
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket一、引子文件,作为常见的数据源。关于操作文件的字节流就是 —FileInputStream&amp;FileOutputStream。
作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节。交流QQ群:【编程之美 365234583】http://qm.qq.com/cgi-bin/qm/qr?k=FhFAoaWwjP29_Aonqz
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程与多线程 线程是什么? 线程(Thread)是一个对象(Object)。用来干什么?Java 线程(也称 JVM 线程)是 Java 进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。 Ja
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket在面向对象编程中,编程人员应该在意“资源”。比如?1String hello = &quot;hello&quot;; 在代码中,我们
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 《程序兵法:Java String 源码的排序算法(一)》 文章工程:* JDK 1.8* 工程名:algorithm-core-le
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 一、父子类变量名相同会咋样? 有个小故事,今天群里面有个人问下面如图输出什么? 我回答:60。但这是错的,答案结果是 40 。我知错能改,然后说了下父子类变
作者:泥瓦匠 出处:https://www.bysocket.com/2021-10-26/mac-create-files-from-the-root-directory.html Mac 操作系统挺适合开发者进行写代码,最近碰到了一个问题,问题是如何在 macOS 根目录创建文件夹。不同的 ma
作者:李强强上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算。这一讲,泥瓦匠带你走进Java中的进制详解。一、引子在Java世界里,99%的工作都是处理这高层。那么二进制,字节码这些会在哪里用到呢?自问自答:在跨平台的时候,就凸显神功了。比如说文件读写,数据通信,还
1 线程中断 1.1 什么是线程中断? 线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 方法,使得该线程中断标志位属性改变。 深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want需求 项目在设计表的时候,要处理并发多的一些数据,类似订单号不能重复,要保持唯一。原本以为来个时间戳,精确到毫秒应该不错了。后来觉得是错了,测试环境下很多一
纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 加微信:bysocket01
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want.文章Points:1、介绍RESTful架构风格2、Spring配置CXF3、三层初设计,实现WebService接口层4、撰写HTTPClient 客户
Writer :BYSocket(泥沙砖瓦浆木匠)什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道“就一个回调…”。此时千万个草泥马飞奔而过(逃哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉。不妨总结总结。一、什么是回调回调,回调。要先有调用,才有调用者和被调用者之间的回调。所以在百
Writer :BYSocket(泥沙砖瓦浆木匠)一、什么大小端?大小端在计算机业界,Endian表示数据在存储器中的存放顺序。百度百科如下叙述之:大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加
What is a programming language? Before introducing compilation and decompilation, let&#39;s briefly introduce the Programming Language. Programming la
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket泥瓦匠喜欢Java,文章总是扯扯Java。 I/O 基础,就是二进制,也就是Bit。一、Bit与二进制什么是Bit(位)呢?位是CPU
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocket一、前言 泥瓦匠最近被项目搞的天昏地暗。发现有些要给自己一些目标,关于技术的目标:专注很重要。专注Java 基础 + H5(学习) 其他操作系统,算法,数据结构当成课外书博览。有时候,就是那样你越是专注方面越