在 JVM 眼中 .class 文件是什么样的?值得收藏

00 前言
JAVA程序具有 " Write Once , Run Anywhere ." 的跨平台特性 。实现这样的目的 , Java的方案是:半编译 + 半解释 , 即 .Class + JVM。

在 JVM 眼中 .class 文件是什么样的?值得收藏

文章插图
 
1、源程序内容会被编译为.Class文件 , .Class文件具有严格规定如何从中提取信息 , 可以理解为 “中间码” , 约定使用者如何理解文件内容
2、理解了程序内容 , 各个平台根据自身特色不同 , 实现各自的JVM用来解释(翻译).Class文件 , 变成真正的本地可执行指令 。
如此实现了Java跨平台的特性 。因此 , 跨平台的基础为.Class , 实现为JVM 。
本文的目的为:读懂.Class , 悉知编写的程序代码在JVM眼中是什么样子 。而在理解了.Class之后 , 对于理解JVM、理解字节码插桩等有进一步帮助 。
01 基础知识
字节码
字节码是一种包含执行程序 , 由数据对组成的二进制文件 , 是一种中间码 。一般来说 , 一字节占用8位 , 即包含八位的二进制 。
文章所指的.Class文件为字节码文件 , 每字节用16进制表示 , 数值范围 00 ~ FF (0 ~ 255).
无符号数基本类型
无符号数可以用来描述数字、索引引用、数值量或按照 UTF-8 编码构成字符串 。u1、u2、u4、u8分别代表 1个字节、2个字节、4个字节和8个字节的无符号数 。
字面量
字面量是一种固定值的表示法 , 本身没有含义 , 需要场景来为它赋予含义 , 如何理解?比如 007 没有含义 , 但是用来表示詹姆斯·邦德 , 你就知道007代表一个很厉害的特工 。在程序中 , int x = 10、String s = "10" 让字面量 10 具有了不同的意义 。
全限定名
将一个类的全限定名是将类全名的.全部替换为/ , 如java.lang.String替换为java/lang/String
描述符
描述符用来描述字段的数据类型、方法的参数类表和返回值 , 每种符号对应不同数据类型
在 JVM 眼中 .class 文件是什么样的?值得收藏

文章插图
 
02 Class文件
Java文件包含了一个类的所有信息 , 以下是一个Java类:
import java.io.Serializable;
public class TestClass implements Serializable{
private int m = 123;
private static int x = 10;
private static final int y = 20;
public int increace(){
return m+1;
}
public void m() throws Exception{
// 具体逻辑不写
}
public static String hello(){
return "hello word";
}
}
此Java文件中 , 所包含的信息有:
类明为TestClass并可被外部访问 , 实现了Serializable接口
拥有类变量 x和y , 拥有成员变量 m
拥有可被外部访问的类函数 hello() , 拥有可被外部访问的成员函数increace() 和 m()
note: 如无特殊说明 , 文章所说.Class文件均由此Java文件编译得来这些信息在被编译后将在.Class文件中进行表达 。通过命令
Javac fileName.java
可将Java文件编译成对应的.Class文件 。.Class文件为字节码文件 , 可借助对应编辑器阅读 。
本文使用的编辑器为 “010”  , windows 和 mac 都有 ,  自行下载 。
在 JVM 眼中 .class 文件是什么样的?值得收藏

文章插图
 
Class 字节码实例文件
.Class文件使用字节码表达信息 , 各数据间紧凑 , 不包含任何分隔符 , 因此整个.Class文件中存储的内容几乎是全部程序运行时的必要数据 。如何解析字节码数据 , 就需要制定规则来解读 , 严格遵守 。
.Class 文件风格采用类似于C语言结构的伪结构来存储数据 。可以将.Class文件看成多张表的集合 , 通过表索引 , 能找到对应的数据 。可以理解为 , 数据存在的相对位置 , 决定了它被赋予的涵义 。
.Class文件格式如下表
在 JVM 眼中 .class 文件是什么样的?值得收藏

文章插图
 
有些数据信息是定长的 , 有些视具体情况而定 , 但都会有相应的约束告知具体长度 。各信息对应已在.Class实例文件图标出 , 剩下的是逐层去解析类信息 。
03 常量池
常量池中主要存放两大类:字面量和符号引用 。符号引用包括:


推荐阅读