JVM系列之Class类文件(从源码到Class类文件)

Posted smileNicky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM系列之Class类文件(从源码到Class类文件)相关的知识,希望对你有一定的参考价值。

JVM系列之Class类文件(从源码到Class类文件)

系列博客专栏:

1、Java虚拟机学习过程

画图表示Java文件从编译到Java虚拟机的大致过程:
在这里插入图片描述

  • (1)、java源代码经过javac编译为class类文件
  • (2)、class类文件经过类加载器ClassLoader被加载到虚拟机
  • (3)、Java虚拟机各种执行过程(垃圾回收、本地调用等等)

2、Java源码到类文件

2.1、前期编译

随意找个.java文件,

javac -g:vars Test.java ---> Test.class

前期编译大致过程 :
Test.java->词法分析器->tokens流->语法分析器->语法树/抽象语法树->
语义分析器->注解抽象语法树->字节码生成器->Test.class文件

2.2、16进制查看

找到class文件,用文本编辑器16进制查看器打开

CA FE BA BE 00 00 00 32  00 9F 0A 00 28 00 5D 07
00 5E 0A 00 02 00 5D 0A  00 02 00 5F 0A 00 60 00
61 0A 00 60 00 62 05 00  00 00 00 00 02 BF 20 05
00 00 00 00 00 00 00 B4  07 00 63 0A 00 0B 00 5D
08 00 64 0A 00 0B 00 65  0A 00 0B 00 66 0A 00 27
00 67 08 00 68 0A 00 69  00 6A 08 00 6B 0A 00 25
00 6C 0A 00 69 00 6D 0A  00 69 00 6E 0A 00 27 00
6F 07 00 70 0A 00 18 00  71 07 00 72 0A 00 1A 00
71 07 00 73 0A 00 1C 00  5D 0A 00 74 00 75 0A 00
25 00 76 08 00 77 0A 00  1C 00 78 0A 00 1C 00 66
0A 00 79 00 7A 0A 00 25  00 7B 07 00 7C 0A 00 25
00 7D 07 00 7E 07 00 7F  01 00 06 3C 69 6E 69 74
3E 01 00 03 28 29 56 01  00 04 43 6F 64 65 01 00
0F 4C 69 6E 65 4E 75 6D  62 65 72 54 61 62 6C 65
01 00 12 4C 6F 63 61 6C  56 61 72 69 61 62 6C 65
 ...

2.3、class文件结构

参考官网,一个class文件由一个单一的ClassFile结构组成:

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];
}
  • u4 magic;

magic:The magic item supplies the magic number identifying the class file
format

魔法数字,固定为CAFEBABE,比如刚才的class文件用16进制编辑查看:

CA FE BA BE 00 00 00 32  00 9F 0A 00 28 00 5D 07
00 5E 0A 00 02 00 5D 0A  00 02 00 5F 0A 00 60 00
61 0A 00 60 00 62 05 00  00 00 00 00 02 BF 20 05
00 00 00 00 00 00 00 B4  07 00 63 0A 00 0B 00 5D
  • u2 minor_version;u2 major_version;

拿刚才的16进制数据

00 00 00 32

其中u2表示minor version,00 0016进制进行10进制转换,就是0;第2个u2继续取 00 32再次进行10进制转换表示10进制的50,也就是jdk6

Java 类文件主要版本到实际 Java JDK 版本的映射

Major VersionMinor VersionJava version
4531.0
4531.1
4601.2
4701.3
4801.4
4905
5006
5107
5208
5309
54010
55011
56012
57013
58014
  • u2 constant_pool_count;
    取刚才的数据00 9F转为10进制159

constant_pool_count:
The value of the constant_pool_count item is equal to the number of entries
in the constant_pool table plus one.

表示常量池中的数量是158

cp_info constant_pool[constant_pool_count-1]
The constant_pool is a table of structures representing various string
constants, class and interface names, field names, and other constants that
are referred to within the ClassFile structure and its substructures. The
format of each constant_pool table entry is indicated by its first “tag”
byte.
The constant_pool table is indexed from 1 to constant_pool_count - 1.

注意:常量池主要存储字面量(Literal)和符号引用(Symbolic References)
字面量:文本字符串,final修饰等
符号引用:类和接口的全限定名、字段名称和描述符、方法名称和描述符

2.4、javap验证

javap是JDK自带的命令,使用命令javap -v -p Test.class进行反编译,可以查看字节码信息和指令等信息。

信息太多,可以使用命令将日志保存到文件里

javap -v -p Test.class > javaplog.txt

在这里插入图片描述

在这里插入图片描述

2.5、 Constant Pool analysis

参考oracle官网对Jvm的比较详细的描述,

constant_pool表条目都具有以下通用格式

cp_info {
    u1 tag;
    u1 info[];
}

在这里插入图片描述
ok,描述得比较难理解,所以还是以刚才的例子进行说明:

  • (1)、参考官网的CONSTANT_Fieldref_info规范,拿上面例子的16进制数据,继续往下数,u1 tag;,这个表示一个字节,所以就是0A0A表示10进制10,对照表格表示代表的是CONSTANT_Methodref,表示这是一个方法引用
CA FE BA BE 00 00 00 32  00 9F 0A 00 28 00 5D 07
CONSTANT_Fieldref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}

往下数:
u2 class_index;:00 28 ->40(10进制),代表的是class_index,表示该方法所属的类在常量池中的索引
u2 name_and_type_index;:00 5D ->93(10进制),代表的是name_and_type_index,表示该方法的名称和类型的索引

拿刚才的javap信息对对比,确实是这样的,所以按照官网规范就可以进行class文件的学习:
在这里插入图片描述

  • (2) 往下分析,CONSTANT_Class_info,CONSTANT_Class_info结构用于表示一个类或一个接口
CA FE BA BE 00 00 00 32  00 9F 0A 00 28 00 5D 07
00 5E 0A 00 02 00 5D 0A  00 02 00 5F 0A 00 60 00

07->7(10进制),对比表格表示CONSTANT_Class

CONSTANT_Class_info {
    u1 tag;
    u2 name_index;
}

u2 name_index;:00 5E->94(10进制),类或接口名称索引

#2 = Class #94 // java/util/Date

ok,按照官网规范,学会怎么看之后,就比较容易理解,javap其它就不详细描述了,按照官网规范对就行

在这里插入图片描述

以上是关于JVM系列之Class类文件(从源码到Class类文件)的主要内容,如果未能解决你的问题,请参考以下文章

JVM系列之Class初始化过程

JVM系列 - JVM类加载机制详解

java之JVM学习--简单理解编译和运行的过程之概览

java之深入理解JVM

JVM源码系列:JVM内部运行之Class的Method

JVM源码系列:JVM内部运行之Class的Method