JVM常量的含义与反编译助记符详解
1、定义一个常量
public class MyTest2 {
public static void main(String[] args) {
System.out.println(MyParent2.str);
}
} class MyParent2{ public static final String str = "hello world"; static {
System.out.println("MyParent2 static block");
} }
打印结果:
hello world
此时MyParent2类不会进行实例化,因为str是一个常量。常量在编译阶段,会存如调用这个常量的方法所在类的常量池中。本质上,调用类并没有直接引用到定义常量的类,因此并不会触发定义常量的类初始化。
注意: 这里值的是将常量str存放到MyTest2类的常量池中,之后MyTest2和MyParent2就没有任何关系了。甚至,我们可以将MyParent2的class文件删除。
2.使用javap反编译class文件(jdk版本1.7)
命令:javap -c MyTest2.class
3: ldc #3 // String hello world
说明System.out.println(MyChild1.str); 这行代码已经成为hello world
3、增加一个short类型的常量
public class MyTest2 {
public static void main(String[] args) {
System.out.println(MyParent2.s);
}
} class MyParent2{ public static final String str = "hello world"; public static final short s = 8; static {
System.out.println("MyParent2 static block");
} }
反编译
此时已经变为bipush
4、助记符:
1)、ldc表示将int,float或是String类型的常量值从常量池中推送至栈顶。 (public static final String str = "hello world";)
2)、bipush 表示将单字节(-128 ~ 127)的常量推送至栈顶(public static final short s = 8;)
3)、sipush表示将一个短整型常量值(-32678 ~ 32676)推送至栈顶 (public static final int i = 128;)
4)、iconst_1 表示将int类型的1推送至栈顶(iconst_m1, iconst_0, iconst_1 ~ icont_5 -1到5)(public static final short m = 1)
5、助记符相关的类
每个助记符都有相关的类
1)LDC
2) ICONST.java源码
在包com.sun.org.apache.bcel.internal.generic;下
6、编译期常量与运行期的常量的区别
创建MyParent3类,里面有一个常量,但这个常量是UUID
public class MyTest3 {
public static void main(String[] args) {
System.out.println(MyParent3.str);
}
} class MyParent3{
public static final String str = UUID.randomUUID().toString(); static {
System.out.println("MyParent3 static code");
}
}
打印输出:
MyParent3 static code
a8be85e9-ef3c-4fd9-88aa-56b2c377a25c
总结: 当一个常量的值并非编译期间可以确定的,那么其值就不会被放到调用类的常量池中,这时在程序运行时,会导致主动使用这个常量所在的类,显然会导致这个类被初始化
最新文章
- jQuery学习之路(8)- 表单验证插件-Validation
- Android多线程编程之AsyncTask
- NoSQL数据库介绍
- SpringMVC从入门到精通之第一章
- 程序的删除kill、killall
- 还有人在用SQL Server 2000或2005吗? 2014来了!
- 3.工厂方法模式(Factory Method)
- [转]asp.net mvc 从数据库中读取图片
- JAVA面试基础
- ES6的promise的学习
- 通过 Xshell 5 连接 centOS 7 服务器
- poj 3436 (最大流)
- 【J2SE】java实现简单照片查看器
- JDK版本不匹配...
- 自制VTP实验总结
- 一篇详细的linux中shell语言的字符串处理
- [PHP] 多表外连接性能测试及优化
- 《Java 9 揭秘》全目录汇总
- Java读取文件-BufferedReader/FileReader/InputStreamReader/FileInputStream的关系和区别
- 登录PeopleTools 提示ora-00942表视图不存在 select xxx from sysadm.psoprdefn