You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中Compile Time与RunTime求值的区别及内存分配疑问

Java编译期求值(Compile Time Evaluation)与运行期求值(RunTime Evaluation)的区别

先明确核心定义:

  • 编译期求值:编译器在将Java源码编译为字节码的阶段,就直接计算出表达式的确定结果,把结果写入字节码中,程序运行时无需再做计算。
  • 运行期求值:表达式的结果只能在JVM运行程序时,根据当时的变量状态、上下文动态计算得出,编译阶段无法确定最终值。

示例1:字面量拼接的编译期求值

代码:

String str = "Hi" + "Bye";
  • 这确实属于编译期求值。编译器会在编译阶段直接把"Hi" + "Bye"合并成完整的字符串"HiBye",生成的字节码里会直接让str指向字符串常量池中的"HiBye"实例。
  • JVM运行时操作:直接从字符串常量池获取该实例,不会在堆上分配新内存(除非常量池原本没有"HiBye",此时会在类加载阶段先在常量池创建该实例,不属于运行时动态分配)。

示例2:变量参与拼接的运行期求值

代码:

String a = "Hi";
String result = a + "hello";
  • 这属于运行期求值。因为a是一个变量,编译器不会假设它的值永远固定(比如a可能在后续代码中被修改,或是方法参数传入的动态值),所以无法在编译阶段确定拼接结果。
  • JVM运行时操作:会通过StringBuilder(Java 5及以后版本)完成拼接:先创建StringBuilder实例,依次调用append("Hi")和append("hello"),最后调用toString()生成新的字符串对象,这个新对象会被分配在堆内存中(默认不会存入字符串常量池,除非显式调用intern()方法)。

核心区别总结

  • 执行时机:编译期求值发生在源码编译为字节码阶段;运行期求值发生在JVM执行字节码的运行阶段。
  • 值的确定性:编译期求值要求表达式的所有操作数都是编译期常量(比如字面量、final修饰的常量变量等);运行期求值依赖运行时的动态数据。
  • 性能影响:编译期求值提前完成计算,节省运行时的CPU和内存资源;运行期求值需要在运行时实时计算,会消耗额外的运行资源。
  • 内存分配:编译期生成的字符串常量通常存储在字符串常量池(属于方法区/元空间);运行期动态生成的字符串对象默认分配在堆内存。

内容的提问来源于stack exchange,提问作者Boris Hartiník

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 08:30:10