专栏首页EffectiveCodingJVM《六 Class 文件的解析》

JVM《六 Class 文件的解析》

上一篇说的是类加载机制,其中刚开始装载阶段是对二进制流进行装载或者解析对应的 .class 文件。

而这一篇要说的就是那个被加载的 .class 文件,也顺道说一下 .Java 文件的编译过程,也就是如何变为 .class 文件的。

Class 文件组成是由JVM字节码组成的,这些字节码组成了我们的这个类中的所有内容。

说一下大体的结构&组成。(装作英文很好的样子)

1、按照惯例,开头几位是标示为class 文件的魔数(magic)。

2、然后是版本号,主版本号,次版本号(version)

3、然后是常量池入口(constant_pool)

其中呢,常量池主要存放两大类常量:字面量(“123” 这就是个字面量)、符号引用

其中符号引用呢,就是类或者接口的全限定标示、字段名称&描述符(public static 这种)、方法名&描述符

JVM是在加载Class 文件时才会进行动态链接,也就是说我们class 文件中压根仅仅是存储而非保存最终的一些内存布局信息(这个是JVM通过解析文件然后分类信息,然后进行标示存放的)

说到了符号引用,还有一个类似的东西叫做直接引用,直接引用是一种能直接找到目标的指针或者偏移量、再或者句柄。如果产生直接引用了,也基本上就是在运行状态了。

4、访问表示(access_flag)

比如这个class 是public、final、abstrack什么的。同样也是一个十六进制的标示

5、然后是这个类一些外围关系吧(this_class、super_class、interface)

6、fields 字段表。这就是存放该class 类变量、对象变量的地方。这个并不完全是按照Java 文件来的。也就是说会默认为我们添加一些东西(注意 这里添加其实是一些补充(比如内部类对于外围类的指向)、而非这种从父类继承来的东西)

7、然后是方法表 (methods)

就是用来存放方法的。这一块,同样会添加一些原本没有的函数,比如Clinit 、init 。

8、属性表(attributes)

上面描述的几类都会有自己的属性表集合,做用呢,就是描述特殊场景的专有信息。(比如异常啊、内部类啊、编译器添加啊、源码与编译后的行号关系啊、源码文件的名称啊这类的东西)

然后放一个demo更清晰吧

image.png

这么一个类,它的class文件是这样的

image.png

这就是Class 文件的一个大体的结构

具体的解析实际上就是把我们静态存储结构校验并且转为运行时数据结构的过程。由存储结构到可执行结构。然后可执行结构再由JVM 驱动解释执行。

那 .Java 是如何变为 .class 的呢

其实这个过程不同的编译器具体过程是不同的,但是还是大体能总结出一个流程。

画个图吧。

image.png

然后在中间过程中编译器会对我们的代码进行一种叫做编译优化的优化。比如字面量拼接啊之类的。这个与内容无关不赘述。

image.png

然后Java 文件什么结构我们很清楚、Java文件怎么变为class 文件现在也已经都知道了,那class 文件产生的指令如何驱动我们计算机执行呢,这个其实就是执行引擎来驱动执行的。有兴趣可以去看看,也挺好玩的,不过感觉这个虽说是JVM很重要的一部分,但是感觉已经不属于我们能左右的Java的部分了~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用Java实现JVM第三章《解析class文件》

    本案例主要介绍通过java代码从class文件中解析;class文件、常量池、属性表;

    小傅哥
  • 用Java实现JVM第三章《解析class文件》

    案例介绍 本案例主要介绍通过java代码从class文件中解析;class文件、常量池、属性表;

    小傅哥
  • (六)-class文件结构1 什么是JVM的“无关性”?2 纵观Class文件结构

    JavaEdge
  • JVM class文件格式

    x.java 通过javac命令生成x.class x.class通过java命令执行。通过classloader load到内存。代码经常需要引用java类...

    lovelife110
  • jvm| class文件认识

    https://www.cnblogs.com/lrh-xl/p/5351182.html

    heidsoft
  • 用Java实现JVM第三章《解析class文件》附[classReader拆解]

    案例介绍 按照如下虚拟机规范,本文主要介绍java版本jvm提取class字节码方式。在java中没有无符号类型,例如js中byte取值是0~255、java中...

    小傅哥
  • 用Java实现JVM第三章《解析class文件》附[classReader拆解]

    按照如下虚拟机规范,本文主要介绍java版本jvm提取class字节码方式。在java中没有无符号类型,例如js中byte取值是0~256、java中是-128...

    小傅哥
  • JVM详解之:java class文件的密码本

    一切的一切都是从javac开始的。从那一刻开始,java文件就从我们肉眼可分辨的文本文件,变成了冷冰冰的二进制文件。

    程序那些事
  • JVM之Class文件结构

    每一个class文件对应一个类或者接口,但是一个类或者接口不一定生成class文件,classloader直接生成。

    WindWant

扫码关注云+社区

领取腾讯云代金券