jvm-006
一、常量传播优化:
常量在编译阶段,如果能确定其数值,会存入到调用类的常量池中。在运行阶段,调用类和常量定义的类就没有任何关系了(可以将定义类的.class文件删除尝试,也不会报错)。因此,常量的调用不会引起定义类的初始化。
实例代码:
public class TestCode01 {
public static void main(String[] args) {
System.out.println(Poo.a);
}
}
class Poo {
public static final String a = "hello";
static {
System.out.println("静态代码块");
}
}
输出结果:
hello
TestCode01调用了Poo类的常量a,并不会引起Poo类的初始化(静态代码块没有执行)。
二、字节码指令:
反编译查看以上class文件的输入:
执行:javap -c TestCode01.class
Compiled from "TestCode01.java"
public class cn.com.ccxi.test.jvm.TestCode01 {
public cn.com.ccxi.test.jvm.TestCode01();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #22 // String hello
5: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
1、ldc表示:将int型、float型或String型常量值从常量池推送至栈顶。
2、bipush表示:将单字节(byte:-128 ~ 127)的数值从常量池推送至栈顶。
3、sipush表示:将短字节(short:-32768 ~ 32767)的数值从常量池推送至栈顶。
4、icons_1表示:将int型数值1推送至栈顶,类似的还有:icons_2,icons_3,icons_4,icons_5,icons_0,icons_m1(表示-1)