Java编译器是否会进行常量折叠优化?如何验证?
Java编译器是否会进行常量折叠优化?
javac确实会做常量折叠优化,但只针对编译期就能确定值的常量表达式,普通局部变量的运算不会触发这个优化。
为什么你的代码没触发常量折叠?
你代码里的x、y、z是普通局部变量,哪怕初始化值是固定的,javac也不会把它们当成编译期常量——因为变量在运行时存在被修改的可能(哪怕你没写修改逻辑),所以编译器不会提前计算x+y+z的结果,字节码里才会出现先加载三个变量、再逐次相加的指令。
如何验证常量折叠?
要触发常量折叠,得用编译期确定的常量,比如直接用字面量运算,或者用final修饰的不可变常量:
class ConstantFoldDemo { public static void main(String[] args) { // 场景1:字面量直接运算 int a = 123 + 234 + 345; // 场景2:final修饰的编译期常量 final int x = 123; final int y = 234; final int z = 345; int b = x + y + z; } }
用javap -c ConstantFoldDemo查看字节码,会看到a和b的赋值指令直接加载702(123+234+345的结果),没有iadd相加操作:
public static void main(java.lang.String[]); Code: 0: sipush 702 3: istore_1 4: sipush 702 7: istore_2 8: return
额外说明
javac确实没有GCC那样的多级优化选项,它的编译期优化比较有限,主要处理常量表达式、语法糖(比如foreach转for循环)这类场景。更复杂的运行时优化,比如普通局部变量的运算折叠,会交给JVM的JIT编译器在程序运行时完成。
内容的提问来源于stack exchange,提问作者wang kai
相关产品推荐
相关产品推荐

