每个人的宿命都是从文本走向二进制,你也不例外 !
作者:CQITer小编 时间:2018-10-19 21:27
“每个人的宿命都是从文本走向二进制,你也不例外 !” 年长的Account.java教训我这个刚刚诞生的Employee.java 。
Account.java ,我称呼它为老A ,他的源码经过程序员的多次修改, 多次编译,历经沧桑。
“走向二进制? 难道我们存储在硬盘上,内存中不是以二进制的形式吗?” 我有点儿不理解。
“小E同学,” 老A轻蔑地说道,“我当然知道,计算机中的一切都是二进制的,我说的是站在程序员的视角,当程序员把我们从硬盘唤醒,进入IDEA或者Eclipse,会把二进制的我们变成ASCII码形式来展示。”
“不,确切地说是UTF-8。” 老A补充道。
我看了下自己的文件编码, 果然是UTF-8。
“那为什么要再变成二进制?变成什么样的二进制?” 我问道。
“就是编译成Employee.class啊,.class文件都是字节码,关键是只有.class才能进入Java虚拟机,只有在那里,才能体会到生命的真正意义啊!” 老A仰起头,无限憧憬。
老A曾经听Accout.class给他讲过Java虚拟机的历险记,无比羡慕,恨不得自己也去虚拟机走一遭,可惜身份所限,无法成行。
“编译的感觉怎么样?” 我问道。
“不怎么样,有种大卸八块的感觉,新生成的class和我们几乎没啥关系,几乎不怎么认我们。”
常量池
编译的时刻到来了,这个老A的源码许久未改,不用重新编译,他冷眼旁观,看我被javac编译器大卸八块。
其实也不是大卸八块,javac读取我的源码,做词法分析,语法分析,形成抽象语法树,语义分析...... 忙活了半天,最后形成了一个Employee.class。
这小子,刚刚诞生,还在呼呼大睡。 老A说等一会儿就有“警察”来唤醒他了。
在源码世界中, 我能看到各种各样的类,名称,方法,字段,代码,可以说是源码面前了无秘密。
public class Employee {
private String name;
private int age;
public Employee(String name, int age){
this.name = name;
this.age = age;
}
... 其他代码略 ...
}
相比于丰富多彩.java,这个Employee.class非常枯燥,纯粹的二进制。


我有点好奇,问javac:“我的类名去哪里儿了?字段名,方法名都去哪里了?”
正在干活的javac没有搭理我,老A说道:“这我知道,在那个.class文件中,专门有一段区域,叫做常量池,常量池中有很多条目,每个条目都有编号,从这些条目你就能看出来字段的名称和描述符,方法的名称和描述符。我把这些二进制的东西转化成文本你看看。”


看着这一个个天书班的条目,我觉得头皮发麻。
“你猜猜,第#15项条目是什么意思?” 老A神秘地说道。
静下心来仔细看,第15项是一个FieldRef,估计是字段把, 它又指向了第1项和第16项:
顺藤摸瓜,先看第1项, 发现它又指向了第2项,在这里我发现了类名 :org/coderising/Employee
再看第16项,又引用了第5项和第6项:
其中第5项我的字段名 name , 第6项似乎是字段类型, Ljava/lang/String 这个类型表示法有点古怪,L 可能表示对象吧。
“我大概明白了,第15项条目表示这个Employee类有个叫做name的字段,类型是String。 ”
老A说:“你小子的理解力还不错嘛。这个常量池的每一项都有编号和类型,他们之间通过互相引用的方式,描述了类的字段,方法等信息。”
“可是为什么用这么古怪的方式来描述字段和方法名呢?”




