我们都知道那句著名的广告语——“WriteOnce,RunAnywhere(写一次,随处运行)”,这和Java无关平台性的精确概括。字节码+JVM使其平台无关,同时也衍生出另一种独立性——语言独立性。像Kotlin、Groovy、Scala、Clojure、JR??uby等语言都可以运行在JVM之上。从理论上讲,只要源代码能够编译成符合JVM规范的字节码,任何语言都可以在JVM中运行。字节码是连接语言和JVM的关键桥梁,今天我们就来聊聊这个关键人物。概述我们创建一个User类:packagecom.shuijing;publicclassUser{}然后通过javac命令编译得到User.class文件。然后用支持十六进制的文本工具(比如sublime)打开,会看到如下内容:在一堆看似不规则的字符中,我们发现前几个字似乎有一些特殊的含义——cafebabe,coffee婴儿?是的,这也解释了为什么Java的商标是一杯热气腾腾的咖啡。前四个字节叫做MagicNumber,它的唯一作用就是判断这是一个JVM可以接受的Class文件。Class文件中没有分隔符,每个数据项都是按顺序排列的。哪个字节代表什么意思,谁在谁旁边,长度都是规定的,不能改变。Class文件结构首先看一个Class文件的标准结构:ClassFile{u4magic;u2次要版本;u2主要版本;u2constant_pool_count;cp_infoconstant_pool[constant_pool_count-1];u2访问标志;u2这个类;interfaces_count];u2字段数;field_info字段[fields_count];u2方法计数;method_info方法[methods_count];u2属性计数;attribute_infoattributes[attributes_count];}来自《The Java Virtual Machine Specification》JavaSE8版如上图,Class文件包含两种数据类型:“unsignednumber”和“list”。无符号数是基本类型,u1、u2、u4、u8分别表示1字节、2字节、4字节、8字节的无符号数。无符号数可以描述数字、索引引用、数量值或以UTF-8编码的字符串。一个表由多个无符号数或其他表(复杂对象)组成,以“_info”结尾。一个Class文件可以看作是一张表。各数据项说明:nametypequantitydescriptionmagicu41magicnumber:CAFEBABEminor_versionu21minor_versionu21major_versionu21majorversionconstant_pool_countu21常量池计数constant_poolcp_infoconstant_pool_count-1常量池access_flagsu21访问标志this_classu21类索引super_classu21父类索引interfaces_coutu22interface_coutu21setinterfaceindexcountfieldsfield_infofields_countucount1setfieldmethodscountmethodsmethod_infomethods_countmethodsetattributes_countu21attributecountattributesattribute_infoattributes_count属性设置顺序是从上到下,严格限定,不可修改。下面用一张更形象的图来展示Class文件的结构:如何查看我们可以使用JDK自带的“javap”命令查看Class文件的字节码信息:javap-vUser.class和你会看到如下信息:另外也可以通过IDEA插件查看,会更友好。效果如下:Plug-in:JClassLib完成了字节码的学习,使得之前只知道的知识变成了已知的。今天先挖个小(大)坑。如果你对字节码感兴趣,可以留言告诉我。后面会详细讨论(填)坑。
