专栏首页Java知己我说精通字符串,面试官竟然问我 Java 中的 String 有没有长度限制?

我说精通字符串,面试官竟然问我 Java 中的 String 有没有长度限制?

String 是 Java 中很重要的一个数据类型,除了基本数据类型以外,String 是被使用的最广泛的了,但是,关于 String,其实还是有很多东西容易被忽略的。

就如本文我们要讨论的问题:Java 中的 String 有没有长度限制?

这个问题要分两个阶段看,分别是编译期和运行期。不同的时期限制不一样。

01 编译期

首先,我们先来合理的推断一下,当我们在代码中使用 String s = ""; 的形式来定义 String 对象的时候,"" 中字符的个数有没有限制呢?

既然是合理的推断,那就要要足够的依据,所以我们可以从 String 的源码入手,根据 public String(char value[], int offset, int count) 的定义,count 是 int 类型的,所以,char value[] 中最多可以保存 Integer.MAX_VALUE 个, 即 2147483647 字符。(jdk1.8.0_73)

但是,实验证明,String s = ""; 中,最多可以有 65534 个字符。如果超过这个个数。就会在编译期报错。

public static void main(String[] args) {

          String s = "a...a";

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

          String s1 = "a...a";

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

}

以上代码,会在 String s1 = "a...a";// 共 65535 个 a 处编译失败:

✗ javac StringLenghDemo.java

StringLenghDemo.java:11: 错误: 常量字符串过长

明明说好的长度限制是 2147483647,为什么 65535 个字符就无法编译了呢?

当我们使用字符串字面量直接定义 String 的时候,是会把字符串在常量池中存储一份的。那么上面提到的 65534 其实是常量池的限制。

常量池中的每一种数据项也有自己的类型。Java 中的 UTF-8 编码的 Unicode 字符串在常量池中以 CONSTANT_Utf8 类型表示。

CONSTANTUtf8info 是一个 CONSTANTUtf8 类型的常量池数据项,它存储的是一个常量字符串。常量池中的所有字面量几乎都是通过 CONSTANTUtf8info 描述的。CONSTANTUtf8_info 的定义如下:

CONSTANT_Utf8_info {

     u1 tag;

     u2 length;

     u1 bytes[length];

}

由于本文的重点并不是 CONSTANTUtf8info 的介绍,这里就不详细展开了,我们只需要我们使用字面量定义的字符串在 class 文件中,是使用 CONSTANTUtf8info 存储的,而 CONSTANTUtf8info 中有 u2 length; 表明了该类型存储数据的长度。

u2 是无符号的 16 位整数,因此理论上允许的的最大长度是 2^16=65536。而 java class 文件是使用一种变体 UTF-8 格式来存放字符的,null 值使用两个 字节来表示,因此只剩下 65536- 2 = 65534 个字节。

关于这一点,在 the class file format spec 中也有明确说明:

The length of field and method names, field and method descriptors, and other constant string values is limited to 65535 characters by the 16-bit unsigned length item of the CONSTANTUtf8info structure (§4.4.7). Note that the limit is on the number of bytes in the encoding and not on the number of encoded characters. UTF-8 encodes some characters using two or three bytes. Thus, strings incorporating multibyte characters are further constrained.

也就是说,在 Java 中,所有需要保存在常量池中的数据,长度最大不能超过 65535,这当然也包括字符串的定义咯。

正是金九银十跳槽季,为大家收集了2019年最新的面试资料,有文档、有攻略、有视频。有需要的同学可以在公众号【Java知己】,发送【面试】领取最新面试资料攻略!暗号【1024】千万不要发,否则.....

02 运行期

上面提到的这种 String 长度的限制是编译期的限制,也就是使用 String s= ""; 这种字面值方式定义的时候才会有的限制。

那么。String 在运行期有没有限制呢,答案是有的,就是我们前文提到的那个 Integer.MAX_VALUE ,这个值约等于 4G,在运行期,如果 String 的长度超过这个范围,就可能会抛出异常。(在 jdk 1.9 之前)

int 是一个 32 位变量类型,取正数部分来算的话,他们最长可以有

2^31-1 =2147483647 个 16-bit Unicodecharacter

2147483647 * 16 = 34359738352 位

34359738352 / 8 = 4294967294 (Byte)

4294967294 / 1024 = 4194303.998046875 (KB)

4194303.998046875 / 1024 = 4095.9999980926513671875 (MB)

4095.9999980926513671875 / 1024 = 3.99999999813735485076904296875 (GB)

觉得不错的话就点个好看再走呗~

原文链接:https://www.cnblogs.com/java-friend/p/11678317.html

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 你知道Java的四种引用类型吗?

    在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用。在这四个引用类型中,只有强引用FinalReference类是包内可见,其他三种引用类型均为p...

    Java技术江湖
  • 浅谈网路爬虫

    爬虫,又称为网页蜘蛛(spider),就是能够在互联网中检索自己需要的信息的程序或脚本。

    用户4372098
  • 为什么选择 Spring 作为 Java 框架?

    在本文中,我们将讨论 Spring 作为最流行的 Java 框架之一的主要价值体现。

    Java技术江湖
  • jmap错误:unknown CollectedHeap type : class sun.jvm.hotspot.gc_interface.CollectedHeap

    Caused by: java.lang.RuntimeException: unknown CollectedHeap type : class sun.jv...

    陈灬大灬海
  • MyBatis迷信者,清醒点!

    不要以为MyBatis更方便,如果只是用一些简单1+1=2,MyBatis会很简单,但当业务实体之间存在复杂的关联、继承关系时,MyBatis的结果集映射会就比...

    Java技术江湖
  • 从 Spring 集成 MyBatis 到浅析 Java 动态代理

    因为 MyBatis 的易上手性和可控性,使得它成为了 ORM框架中的首选。近日新起了一个项目,所以重新搭建了一下 Spring-mybatis, 下面是搭建笔...

    Java技术江湖
  • 数据结构于算法—线性表详解(顺序表、链表)

    下面用一个图来浅析线性表的关系。可能有些不太确切,但是其中可以参考,并且后面也会根据这个图举例。

    用户4372098
  • JVM原理分析,看了都说好

    JVM是Java Virtual Machine(Java虚拟机)的缩写,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、...

    Java技术江湖
  • 万万没想到,JVM内存结构的面试题可以问的这么难?

    在我的博客中,之前有很多文章介绍过JVM内存结构,相信很多看多我文章的朋友对这部分知识都有一定的了解了。

    Java技术江湖
  • Springboot+shiro基于url身份认证和授权认证

    三个核心组件:Subject, SecurityManager 和 Realms.

    用户4372098

扫码关注云+社区

领取腾讯云代金券