面试官问我String能存储多少个字符串?

  1. 首先String的length方法返回是int。所以理论上长度一定不会超过int的最大值。
  2. 编译器源码如下,限制了字符串长度大于等于65535就会编译不通过
typescript 复制代码
private void checkStringConstant(DiagnosticPosition var1, Object var2) {
    if (this.nerrs == 0 && var2 != null && var2 instanceof String &&   ((String)var2).length() >= 65535) {
        this.log.error(var1, "limit.string", new Object[0]);
        ++this.nerrs;
    }
}

Java中的字符常量都是使用UTF8编码的,UTF8编码使用1~4个字节来表示具体的Unicode字符。所以有的字符占用一个字节,而我们平时所用的大部分中文都需要3个字节来存储。

ini 复制代码
//65534个字母,编译通过
String s1 = "dd..d";

//21845个中文"自",编译通过
String s2 = "自自...自";

//一个英文字母d加上21845个中文"自",编译失败
String s3 = "d自自...自";

对于s1,一个字母d的UTF8编码占用一个字节,65534字母占用65534个字节,长度是65534,长度和存储都没超过限制,所以可以编译通过。

对于s2,一个中文占用3个字节,21845个正好占用65535个字节,而且字符串长度是21845,长度和存储也都没超过限制,所以可以编译通过。

对于s3,一个英文字母d加上21845个中文"自"占用65536个字节,超过了存储最大限制,编译失败。

  1. JVM规范对常量池有所限制。量池中的每一种数据项都有自己的类型。Java中的UTF-8编码的Unicode字符串在常量池中以CONSTANTUtf8类型表示。CONSTANTUtf8的数据结构如下:
ini 复制代码
CONSTANT_Utf8_info {
    u1 tag;
    u2 length;
    u1 bytes[length];
}

我们重点关注下长度为 length 的那个bytes数组,这个数组就是真正存储常量数据的地方,而 length 就是数组可以存储的最大字节数。length 的类型是u2,u2是无符号的16位整数,因此理论上允许的的最大长度是2^16-1=65535。所以上面byte数组的最大长度可以是65535

  1. 运行时限制

    String 运行时的限制主要体现在 String 的构造函数上。下面是 String 的一个构造函数:

arduino 复制代码
public String(char value[], int offset, int count) {
    ...
}

上面的count值就是字符串的最大长度。在Java中,int的最大长度是2^31-1。所以在运行时,String 的最大长度是2^31-1。

但是这个也是理论上的长度,实际的长度还要看你JVM的内存。我们来看下,最大的字符串会占用多大的内存。

(2^31-1)216/8/1024/1024/1024 = 4GB

所以在最坏的情况下,一个最大的字符串要占用4GB的内存。如果你的虚拟机不能分配这么多内存的话,会直接报错的。

JDK9以后对String的存储进行了优化。底层不再使用char数组存储字符串,而是使用byte数组。对于LATIN1字符的字符串可以节省一倍的内存空间。

相关推荐
新时代牛马17 分钟前
PCI与PCIe 硬件原理、配置空间/BAR 与 Linux 驱动完整篇:从 LTSSM、TLP 到 ECAM 与probe
java·linux·服务器
Bs_MoneyMagnet24 分钟前
基于springboot+vue的医疗健康便民服务平台的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring
sunshine22 girl1 小时前
Java学习一 环境配置2 Idea的入门使用和maven配置,项目启动脚本配置
java·maven
有点。2 小时前
*C++哈夫曼树与哈夫曼编码
java·c++·servlet
子兮曰2 小时前
Bun v1.4.1 深度解析:从 Zig 到 Rust,一场 11 天、64 个 AI 代理的语言迁徙
前端·后端·bun
CRMEB系统商城3 小时前
CRMEB标准版系统(Java)v3.1正式发布
java·spring·微信小程序·php·教育电商
写后端的胖头鱼3 小时前
【高频面试题】Java 基础类型 + 包装类 + String 互相转换
java·开发语言
weixin_460443563 小时前
企业考试系统从.NET迁移到Java+Linux:数据库迁移、接口兼容与灰度切换实践
java·煤矿培训考试系统·煤矿在线考试系统·煤矿安全培训·煤矿考试系统·一人一档
香菜TTT3 小时前
Redis的哨兵机制
java·数据库·redis
withoutfear4 小时前
IntelliJ IDEA卡顿内存分配不足和索引被频繁触发问题解决办法
java·ide·intellij-idea