Kotlin字符串最大长度问题:长字符串代码编译失败
Kotlin编译报错:UTF8 string too large 解决方案
我帮你分析下这个问题:你遇到的并不是Java/Kotlin字符串本身的容量限制(毕竟你只有13万多字符,远小于2^31-1的上限),而是JVM字节码常量池的UTF-8字符串长度限制。
问题根源
JVM的常量池规定,存储UTF-8编码的字符串常量时,其字节长度不能超过65535(也就是2^16-1)。你的字符串虽然字符数是138894,但因为大多是ASCII字符,每个字符UTF-8编码后占1字节,总字节数直接超过了65535的阈值,所以编译阶段就触发了UTF8 string too large的错误。
解决办法
这里给你两个实用的解决方案,优先推荐第一个:
1. 从外部文件读取测试数据(最推荐)
既然你本来就是通过代码生成output.txt文件,那基准测试时直接读取文件内容就好,完全没必要把大字符串硬编码到代码里。修改后的基准测试代码如下:
import kotlin.system.* import java.io.File fun main() { val inputs = File("output.txt").readText() val avgTime = measureNanoTime { inputs.reader().forEachLine { line -> val (a, b, c, d, e) = line.split(" ").map(String::toInt) } } / 5000 println(avgTime) }
这样既避开了编译限制,还能让测试数据和代码分离,后续调整测试数据也更方便。
2. 拆分字符串常量(仅当必须硬编码时使用)
如果一定要把字符串写在代码里,可以把大字符串拆分成多个子字符串,每个子字符串UTF-8编码后的字节数不超过65535,然后在运行时拼接:
fun main() { val inputs = """ 1 2 3 4 5 // ... 第一部分内容(字节数<65535) """.trimIndent() + """ // ... 第二部分内容(字节数<65535) 24996 24997 24998 24999 25000 """.trimIndent() measureNanoTime { inputs.reader().forEachLine { line -> val (a, b, c, d, e) = line.split(" ").map(String::toInt) } }.div(5000).let(::println) }
每个拆分后的片段会作为独立的常量池项,编译通过后,运行时拼接就能得到完整的字符串。
内容的提问来源于stack exchange,提问作者Animesh Sahu
相关产品推荐
相关产品推荐

