首先编写一测试程序
public class Test { public static void main(String[] args){ System.out.println("HelloWorld"); } }
执行javac Test.java 得到Test.class文件(编译过程有点复杂,这里先不看)
执行java Test,控制台输出"test",想要弄清楚java程序是怎么运行起来首先得了解清楚class文件
看下Test.class里究竟是什么东西,class文件的内容如下:
上图中都是以16进制表示,接下来挨个分析其中的内容表示什么意思。class文件中存储的数据可以参考下表:
1、magic 魔数
CA FE BA BE
魔数,确定该文件是否是虚拟机可以接受的文件
2、class文件版本信息
00 00 00 33
class文件的版本号,51表示jdk1.7.0
3、常量池
3.1常量池入口
00 1D
常量池数量为29-1=28,每个类只有一个常量池
常量池中放了字符串,常量值,类名称,字段名,方法名等,反编译下Test.class,看看常量池中存放了哪些东西
Constant pool: #1 = Methodref #6.#15 // java/lang/Object."<init>":()V #2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #18 // test #4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V #5 = Class #21 // Test #6 = Class #22 // java/lang/Object #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 main #12 = Utf8 ([Ljava/lang/String;)V #13 = Utf8 SourceFile #14 = Utf8 Test.java #15 = NameAndType #7:#8 // "<init>":()V #16 = Class #23 // java/lang/System #17 = NameAndType #24:#25 // out:Ljava/io/PrintStream; #18 = Utf8 test #19 = Class #26 // java/io/PrintStream #20 = NameAndType #27:#28 // println:(Ljava/lang/String;)V #21 = Utf8 Test #22 = Utf8 java/lang/Object #23 = Utf8 java/lang/System #24 = Utf8 out #25 = Utf8 Ljava/io/PrintStream; #26 = Utf8 java/io/PrintStream #27 = Utf8 println #28 = Utf8 (Ljava/lang/String;)V