咱们都晓得那句驰名的宣传语——「一次编写, 到处运行(Write Once, Run Anywhere)」,这是对 Java 平台无关性的精准概括。字节码 + JVM 使其平台无关,与此同时也衍生出另一个无关性——语言无关性。像 Kotlin、Groovy、Scala、Clojure、JRuby 等语言都能够运行在 JVM 之上。实践上只有能将源代码编译成合乎 JVM 标准的字节码,任何语言都能够在 JVM 中运行。

字节码是连贯语言和 JVM 的要害桥梁,明天咱们就一起聊聊这个关键人物。

概览

咱们创立一个 User 类:

package com.shuijing;public class User {}

而后通过 javac 命令编译,失去 User.class 文件。而后用反对十六进制的文本工具(比方 sublime)关上,你会看到如下内容:

在一堆看似毫无法则的字符中,咱们发现结尾几个字如同有什么特地的含意——cafe babe,咖啡宝贝?没错,这也解释了为啥 Java 的商标是一杯冒着热气的咖啡。结尾这四个字节叫做魔数(Magic Number),它的惟一作用就是确定这是一个能够被 JVM 承受的 Class 文件。

Class 文件中没有任何分隔符, 各数据项严丝合缝顺次排列。哪个字节代表什么含意,谁挨着谁,长度是多少,都是有规定的,不能扭转。

类文件构造

先来看一个 Class 文件的规范构造:

ClassFile {    u4                 magic;    u2                 minor_version;    u2                 major_version;    u2                 constant_pool_count;    cp_info         constant_pool[constant_pool_count-1];    u2                 access_flags;    u2                 this_class;    u2                 super_class;    u2                 interfaces_count;    u2                 interfaces[interfaces_count];    u2                 fields_count;    field_info         fields[fields_count];    u2                 methods_count;    method_info     methods[methods_count];    u2                 attributes_count;    attribute_info     attributes[attributes_count];}
来自《The Java Virtual Machine Specification》Java SE 8 Edition

如上所示,Class 文件中蕴含两种数据类型:「无符号数」和「表」。

无符号数是根本类型,u1、 u2、 u4、 u8 别离示意 1 个字节、 2 个字节、 4 个字节和 8 个字节的无符号数。无符号数能够形容数字、索引援用、数量值或者依照 UTF-8 编码的字符串。

是有多个无符号数或其余表组合而成(简单对象),并且以「_info」结尾。一个 Class 文件能够视作一张表。

各数据项阐明:

名称类型数量阐明
magicu41魔数:CAFE BABE
minor_versionu21次版本
major_versionu21主版本
constant_pool_countu21常量池计数
constant_poolcp_infoconstant_pool_count - 1常量池
access_flagsu21拜访标记
this_classu21类索引
super_classu21父类索引
interfaces_coutu21接口索引计数
interfacesu2interfaces_count接口索引汇合
fields_countu21字段计数
fieldsfield_infofields_count字段汇合
methods_countu21办法计数
methodsmethod_infomethods_count办法汇合
attributes_countu21属性计数
attributesattribute_infoattributes_count属性汇合
程序由上到下,严格限度,不可批改

上面用一张更形象的图展现一下 Class 文件的构造示意:

如何查看

咱们能够通过 JDK 自带的「javap」命令来查看 Class 文件的字节码信息:

javap -v User.class

你会看到如下信息:

另外,还能够通过 IDEA 的插件来查看,会更加敌对一些。成果如下:

插件:JClassLib

完结

学习字节码会让之前只知其然的常识,变得知其所以然。

明天先开(挖)个小(大)头(坑),如果你对字节码感兴趣能够留言通知我,前面咱们再进行详(慢)细(慢)讨(填)论(坑)。