文章目录
1. class 文件的基本格式
2. class 文件的理解
2.1 class 文件是什么?
2.2 class 文件与类对应的关系
定义在 class 文件中
2.3 class 文件格式
大端模式符合人类的习惯
2.4 class文件中包含的内容,将逐一进行解释,如下面所示
A class file consists of a single ClassFile structure:
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];
}
2.4.1 magic u4
文件内容的前几个数用来描述文件类型,这几个字节的内容叫做magic
扩展名字就是文件的后缀,根据后缀进行文件类型的识别;
.class 文件的magic
magic 的使用:
java 虚拟机使用这个magic 进行 .class 文件的识别
2.4.2 minor_version ; major_version(主版本,次版本)u2 u2
不同 javac 进行编译之后,上面显示的额JDK 版本
2.5 常量池总数
2.6 常量池(静态常量池,很多时候,静态常量池指的是class 文件中的常量池)
- Java 程序中编写的常量
- 在 .class 文件中的常量 包含字面量以及符号表
2.6.1 常量池的数据结构
2.6.2 由于tag 的不同,JDK中常量为以下14种
2.6.3 JVM 描述符
描述符是 jvm 层次上的概念,针对 class 文档定义而成,主要用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)。
字段数据类型描述符
对于字段的数据类型,其描述符主要有以下几种
基本数据类型:(byte、char、double、float、int、long、short、boolean):除 long 和 boolean,其他基本数据类型的描述符用对应单词的大写首字母表示。long 用 J 表示,boolean 用 Z 表示。
void:描述符是 V。
对象类型:描述符用字符L加上对象的全限定名表示,如 String 类型的描述符为 Ljava/lang/String。
数组类型:每增加一个维度则在对应的字段描述符前增加一个 [ ,如一维数组 int[] 的描述符为 [I,二维数组 String[][] 的描述符为 [[java/lang/String 。
各类型的描述符汇总如下:
数据类型 描述符
byte B
char C
double D
float F
int I
long J
short S
boolean Z
特殊类型void V
对象类型 L + 对象*全限定名*。如 Ljava/lang/String 表示 String 类型
数组类型 每增加一个维度则在对应的字段描述符前增加一个 [ ,如一维数组 int[] 的描述符为 [I,二维数组 String[][] 的描述符为 [[java/lang/String
全限定名,一个类的全限定名是将类全名的.全部替换为/,示例如下:
me/mingshan/cglib/SampleClass
方法描述符
用描述符来描述方法时,其格式为:(参数列表描述符)返回值描述符。其中参数列表按照方法的参数从左到右依次用描述符对参数进行描述,如果没有参数则不用写。
例如:
方法:void init()的描述符为 ()init;
方法:java.lang.String getName()的描述符为()Ljava/lang/String;
方法:int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex)的描述符为([CII[CIII)I
[C I I [C I I I
2.6.4 使用javap 查看class文件相关信息
javap -v ***.class
将class 文件中的相关信息进行打印,转换成可以让人方便阅读的形式
javap -v MyApp.class
Classfile /E:/JavaProject/Jvm01/out/production/Jvm01/com/luobin/app/MyApp.class
Last modified 2021年7月18日; size 270 bytes
SHA-256 checksum 66e28540874c3814fbd3044dbe28a1c8d2ce09f9f785a7e679803c12f08b2b9e
Compiled from "MyApp.java"
public class com.luobin.app.MyApp
minor version: 0
major version: 55
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #2 // com/luobin/app/MyApp
super_class: #3 // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
Constant pool:
#1 = Methodref #3.#13 // java/lang/Object."<init>":()V
#2 = Class #14 // com/luobin/app/MyApp
#3 = Class #15 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lcom/luobin/app/MyApp;
#11 = Utf8 SourceFile
#12 = Utf8 MyApp.java
#13 = NameAndType #4:#5 // "<init>":()V
#14 = Utf8 com/luobin/app/MyApp
#15 = Utf8 java/lang/Object
{
public com.luobin.app.MyApp();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/luobin/app/MyApp;
}
SourceFile: "MyApp.java"
2.6.5 14个常量的解释
CONSTANT_Class_info
就是你在编写程序的时候,使用了什么类,在此处的CONSTANT_Class_info 中有显示
CONSTANT_Class_info{
u1 tag; // 固定的数值
u2 name_index;
}
使用到了类,也就是将类进行了实例化,此时的 class_info 才会显示相关类的信息;
class_info 中至少显示两个类,一个是自己,另外一个是他的父类
3. JDK JRE JVM 三者关系
3.1 JDK8 中的 Compact Profiles
3.1.1 查看编译的当前程序使用到了哪儿些依赖:使用jdeps -P ***.class
jdeps -P MyApp.class
MyApp.class -> java.base (compact1)
MyApp.class -> java.sql (compact2)
com.luobin.app -> java.io compact1
com.luobin.app -> java.lang compact1
com.luobin.app -> java.lang.invoke compact1
com.luobin.app -> java.sql compact2