你管这破玩意叫 class?
共 7781字,需浏览 16分钟
·
2021-03-23 18:45
public class FlashObject {
private String name;
private int age;
public String getName() {
return name;
}
public int add(int a, int b) {
return a + b;
}
}
public class FlashObject{private String name;private int age;public int add(int a,int b){return a+b;}
1 类信息
![](https://filescdn.proginn.com/b0257613acdb0614d1ca483f2a4138e6/ddd2e7202f3bb878b05630a74b3e80c1.webp)
这里的一个小方格是 1 个字节,也就是 8 位。一个英文字母用 ASCII 码表示为 1 个字节,所以占一个方格,之后不再解释。
![](https://filescdn.proginn.com/869440fbea1f9b0ca05a8c4337e4bd18/2a6a4fa2b185b51ac8d77b3b84fead11.webp)
![](https://filescdn.proginn.com/6a07761034315b0aa8aaabc3b0d077eb/4513276e31a25da0360106790de9d921.webp)
![](https://filescdn.proginn.com/565324ad600a1d639b7a38ae9684f2cd/f2202bd7ed33b911afb63b8310c70aac.webp)
2 常量池
![](https://filescdn.proginn.com/47ffcb55a08e10e2306fa85685e4caf2/087b76093cf820193c3ac77f49b3363f.webp)
![](https://filescdn.proginn.com/55d080a39e9acf9143c78d1aaa827281/92f4166c87a49c86cd72796dc65dcc44.webp)
![](https://filescdn.proginn.com/1387f40e982ed24ddd999885923adf69/2d10db86ba7f3b190760a24b126de86d.webp)
![](https://filescdn.proginn.com/880438721f10420c7f7530118ccabb5f/1159c94c51d94807c0551405c43de5d2.webp)
![](https://filescdn.proginn.com/4919535af65c5f93a760ee834c789190/9cde17abd9585c5272035170e399aa00.webp)
![](https://filescdn.proginn.com/fe2a6c4143abc82700ffecc1b4dfc1e7/76339bfc8c57e53e91e96682dd0d2838.webp)
3 变量
![](https://filescdn.proginn.com/c41fcf403d8964c6cde4500f123db605/3391a11350ba35ed9c1c447e8f105b7e.webp)
先看标记部分
![](https://filescdn.proginn.com/1475af2c664173a08eda0c4df481d9f2/f7600c945afc2fc0fafbf81f8e688e68.webp)
标记 | 值 |
public | 0x0001 |
private | 0x0002 |
protected | 0x0004 |
static | 0x0008 |
final | 0x0010 |
volatile | 0x0040 |
transient | 0x0080 |
![](https://filescdn.proginn.com/aae92330e5bbb1d3b855d75c634a6d92/b6236c3e277fc25c3eb1ab50bb58d595.webp)
再看类型部分
符号表示 | 类型 |
B | byte |
C | char |
D | double |
F | float |
I | int |
J | long |
S | short |
Z | boolean |
LClassName ; | 类 |
[ | 数组 |
![](https://filescdn.proginn.com/fc8da882bd6b192175b82447ac84045d/3da4e0075800910259436b42e3d146c6.webp)
ok,第二部分也搞定了。
再看名字部分
![](https://filescdn.proginn.com/e81dfaff34c6db9a328dc854d71d4df2/e189be476acdf6ca72df69e506c19196.webp)
![](https://filescdn.proginn.com/183423de0cf9351e4a2d1cfdba14ca06/2d607116aea2e785dcb4850f9395cc40.webp)
![](https://filescdn.proginn.com/f1f700eb3f0e0b256f5678dd1b488574/2d32f84e2408edfda733a680c0fbe8db.webp)
4 方法
public int add(int a, int b) {
return a + b;
}
![](https://filescdn.proginn.com/675d7e47c9512504a66d5c0d325f9181/81995a1dec480d1adbffc67d023cb9b1.webp)
标记 | 值 |
public | 0x0001 |
private | 0x0002 |
protected | 0x0004 |
static | 0x0008 |
final | 0x0010 |
volatile | 0x0040 |
transient | 0x0080 |
synchronized | 0x0020 |
native | 0x0100 |
abstract | 0x0400 |
符号表示 | 类型 |
B | byte |
C | char |
D | double |
F | float |
I | int |
J | long |
S | short |
Z | boolean |
LClassName ; | 类 |
[ | 数组 |
V | void |
@RequestMapping()
public String function(String a) throws Exception {
return a;
}
![](https://filescdn.proginn.com/354c82cf3a146f8ce46457e04cc062c4/68f4afd3dc99847760b29573813a46ed.webp)
public int add(int a, int b) {
return a + b;
}
![](https://filescdn.proginn.com/c800b5bd8a56789c344c14d7045b96f3/e257add15b5ff3f3101023ac182f912c.webp)
![](https://filescdn.proginn.com/dc17551dda2f32726c962713b202c9a8/6a69c66180b227a871e86494c55d68f3.webp)
![](https://filescdn.proginn.com/ea984fc5ab8109889baf7fba1ce9e7da/c9cf16392486ec6fd0bc2129ef72eff7.webp)
5 class
![](https://filescdn.proginn.com/7d715efe64a8df2e970e8207e384f93a/8f93f214cc0e1f8754a020bd7d2573cb.webp)
FlashObject.class
后记
根据 Java 虚拟机规范,Java Virtual Machine Specification Java SE 8 Edition,一个 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];
}
我们的设计与它几乎相同。
只有后两项,我们没有涉及到,本身也不是重点。
如果想了解 class 文件的全部细节,最好的办法就是阅读官方文档,也就是 Java 虚拟机规范的第四部分。
Chapter 4. The class File Format
这里的链接可以直接定位:
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2
不要觉得官方文档晦涩难懂,这个部分还是非常清晰明了的,大多数博客基本上对格式的讲解都缺斤少两,而且说得也不形象,还不如直接阅读官方文档呢。
还有一个好的方式,就是直接观察 class 文件的二进制结构解析,这里推荐一个工具
classpy
用这个工具打开一个 class 文件,是这个样子。
左边解析好的树型结构,可以直接和右边的 class 文件的二进制内容相对应,非常好用。
最后,希望大家找时间用这个工具分析一个复杂的 class 文件,会很有帮助的。祝大家学会 class 文件。