调用static final变量时为何static块未优先执行?
为什么调用final static变量时没触发静态代码块?
先看你给出的代码:
class Test4 { public static void main(String as[]) { System.out.println(Hello.x); } } class Hello { final static int x=10; static { System.out.println("Hello"); } }
运行后输出:
10
你疑惑的点完全合理——按常理调用静态变量应该触发类加载,进而执行静态代码块,但这里却没打印"Hello"。核心原因是Java的常量折叠(Constant Folding)机制:
当你定义了final static的基本类型(或者String类型)变量时,编译器在编译阶段就会把这个常量的具体值直接嵌入到所有引用它的代码里。也就是说,编译完成后,Test4类的main方法里的System.out.println(Hello.x);会被直接替换成System.out.println(10);。
这样一来,运行Test4的时候,JVM完全不需要去加载Hello类——因为代码里已经没有对Hello类的实际引用了,自然也就不会执行Hello类的静态代码块。
你可以做两个小实验验证这个逻辑:
- 去掉
final修饰符:把final static int x=10;改成static int x=10;,此时x不再是编译期常量,JVM会加载Hello类,静态代码块会执行,输出会先打印"Hello"再打印10。 - 换成引用类型:把
final static int x=10;改成final static Integer x=10;,即使是final static,引用类型的常量不会被编译器折叠,JVM会加载Hello类,静态代码块也会正常执行。
内容的提问来源于stack exchange,提问作者DEEPAK KUMAR
相关产品推荐
相关产品推荐

