IDEA编译报错“java: 常量字符串过长”的原因及解决方法

2025-02-23 17:50

本文主要是介绍IDEA编译报错“java: 常量字符串过长”的原因及解决方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,...

在线文本换行工具: https://lzltool.cn/Toolkit/WrapWordsInText

一、问题描述

今天在开发过程中,由于尝试将一个文件的 Base64 字符串设置为常量,结果导致 IDEA 编译的时候出现了如下报错:

  • Java: 常量字符串过长

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

二、问题原因

2.1 理论角度

在 Java 中,常量字符串过长的问题通常是 由于编译器对字符串常量的长度有限制 导致的。

众所周知,Java代码是由 Java编译器(javac) 编译为 class 字节码之后运行的。这个报错就是因为 javac 对字符串常量有一个上线,通常是 65534 个字符串。这个限制是由于 Java 编译器在处理字符串常量时,使用了 16位 的无符号证书来表示字符串的长度,因此最大值为 2^16 - 1 = 65535,但实际使用中会减去一个字符的空间用于其他用途,所以最大长度为 65534。

在 IDEA 中编写代码时,如果定义了一个超过 65534 个字符的字符串常量,编译器就会报错:java: 常量字符串过长。

JVM 规范文档: https://docs.oracle.com/javase/specs/jvms/se19/html/jvms-4.html#jvms-4.4.3

查看 JVM 规范文档可以看到:在 Java 中,常量 String 的结构体如下:

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

其中 string_index 指针指向常量池的一个条目,这个条目的结构体格式为 CONSTANT_Utf8_info。这个结构体的定义如下所示:

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

由上图可知,一个 String 类型的常量的最大长度为 2^16 - 1 = 65535,但实际使用中会减去一个字符的空间用于其他用途,所以最大长度为 65534。

2.2 源China编程码角度

下面我们再从 javac 源码角度进行分析,源码下载地址:https://jdk.java.net/java-se-ri/8-MR6。

\lib\src\jdk.compiler\com\sun\tools\javac\jvm|Gen.java 中可以看到如下代码:

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

而这个 PoolWriter.MAX_STRING_LENGTH 的值为:

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

从代码可以看到,要求小于 2^16-1,所以得出 javac 允许常量 String 保存的最大字节数为 0xFFF-1,即 2^16-1-1=65534

三、解决方案

解决方案①:StringBuilder 拼接

我们可以使用 StringBuilder 进行字符串拼接的方式来解决这个问题,只要每次拼接的长度不超过 65534 即可。

public static StrinChina编程g getConstant() {
    StringBuilder builder = new StringBuilder();
    builder.append("字符串1");
    builder.append("字符串2");
    // ...
    return builder.toString();
}
  • 在线文本换行工具: https://lzltool.cn/Toolkit/WrapWordsInText

解决方案②:读取文件内容

还有一种方式是将字符串写入文件后读出来,如下所示:

try (BufferedReader reader = new BufferedReader(new FileReader("longString.txt"))) {
    StringBuilder builder = new StringBuixjOVOlder();
    String line;
    while ((line = reader.readLine() != null)) {
        builder.awww.chinasem.cnppend(line);
    }
    String longString = builder.toString();
} catch (IOExjsception e) {
    e.printStackTrace();
}

除了两种方式,其余几种方式小编亲试均无效:

  • 使用加号连接字符串
  • 使用换行符
  • 使用Eclipse编译器

四、方案验证

我们先创建一个 65535 长度的字符串试一下,结果如下所示,不出意外地报错了:

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

下面我们去掉一个字符,长度调整为 65534,再次执行,就可以正常打印了,如下图所示:

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

现在我们已经确定当长度超过 65534 的时候就会报错了,那么我们将长度改为 65535,然后使用 StringBuilder 来实现,结果如下所示:

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

整理完毕。

到此这篇关于IDEA编译报错“java: 常量字符串过长”的原因及解决方法的文章就介绍到这了,更多相关java常量字符串过长内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于IDEA编译报错“java: 常量字符串过长”的原因及解决方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153507

相关文章

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Maven 配置中的 <mirror>绕过 HTTP 阻断机制的方法

《Maven配置中的<mirror>绕过HTTP阻断机制的方法》:本文主要介绍Maven配置中的<mirror>绕过HTTP阻断机制的方法,本文给大家分享问题原因及解决方案,感兴趣的朋友一... 目录一、问题场景:升级 Maven 后构建失败二、解决方案:通过 <mirror> 配置覆盖默认行为1. 配置示

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

java中long的一些常见用法

《java中long的一些常见用法》在Java中,long是一种基本数据类型,用于表示长整型数值,接下来通过本文给大家介绍java中long的一些常见用法,感兴趣的朋友一起看看吧... 在Java中,long是一种基本数据类型,用于表示长整型数值。它的取值范围比int更大,从-922337203685477

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过