Class文件结构[JVM分支]

目录

1,Class文件理解

Class文件是什么

Class文件与类的关系

Class文件的格式

2,Class文件结构

魔数magic;

版本号minor_version/major_version

class文件中的常量constant

access_flags

this_class

super_class

interfaces_count/interfaces[interfaces_count]

fields_count/fields[fields_count]

注意点

注1,java接口中的基类是否为Object

注2,静态块,实例块,构造方法的实行顺序先执行静态块再实例块接着是构造方法

注3注解生命周期


1,Class文件理解

Class文件是什么

其实java虚拟机是不认识java语言的,他不可能直接通过java语言而运行的程序,他只与class文件这种特定的二进制文件格式所联系

除java外还有Kotlin,Clojure,Groovy,JRuby,JPython,Scala都可以编译出class文件的

class文件包含了java虚拟机的指令集,符号表,其他信息等

Class文件与类的关系

一个class文件对应唯一一个类或者借口的

一个类或者借口不一定只能是class文件因为还有动态代理,也就是类加载器直接生成出来的

Class文件的格式

class文件里面都是二进制,(字节流组成),每个字节都有8个二进制位所有16位32位64位长度的数据将通过构造成2个4个8个连续的8位字节来表示

查看class文件的工具:IDEA的Big-endian插件(大端小端的顺序进行存储)

一个普通的类文件中编译形成的class文件的数据显示:

大端存储就是低位在高地址中 高位数在低地址中 小端模式则相反:(图中是大端模式存储)

 以图中的0034为例如果0034是一个十六进制数那么对他来说他的低位就是34高位是00

所以他将要34放到高地址中,就是07号地址,而00则是高位放在低地址中则是06号地址

2,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文件数据结构采用了两种数据类型:"无符号数"和"表"

无符号数:代表了class文件的内容如果是u1,u2,u4分别代表1,2,4个字节的无符号数

无符号数可以用来描述数字,引用,数值或者按照UTF-8编码构成字符串值

表:是由多个无符号数或者用其他表做数据构成的复合数据类型结尾习惯用_info命名

魔数magic;

class文件结构第一项:u4  magic

magic这里叫魔数占4个字节

魔数就是用四个字节来描述该文件类型的一个项 这四个字节叫做魔数

class文件魔数四个字节:CA    FE    BA      BE也就是(大端)class文件开头的四个字节

魔数的利用:文本文件是没有魔数值的比如txt文件

利用魔数判断文件的真实类型

版本号minor_version/major_version

版本号就是class文件的就是文件的主版本号和次版本号

比如java8版本的版本号就是52      java11则是55      java1.1.8版本则是45.3

major_version主版本起始值为45每个JDK大版本发布会加1

minor_version次版本起始值为0

比如java1.1.8的主版本号就是45次版本号就是3

java8的主版本号52次版本0

注意:JVM是向下兼容而向上不兼容的 如jdk8可以运行jdk及8以下的class文件 则不能运行版本号超过52的class文件

class文件中的常量constant

假设常量池大小为n 常量池真正有效的索引为1到n-1

可以通过idea编译器的jclasslib插件来查看一个文件中的常量池

class文件中的常量:字面量,符号表

符号表类似下标

描述符就是描述数据类型,方法等的

常量池cp_info是一个常量数组每一个元素是一个常量

常量项中有一个tag项tag是标志一个常量是那种常量结构

根据常量不同jdk8中常量分为14种

access_flags

access_flags用来标识一个方法或者类等的访问权限属性

但在java8之后每个类会自动带一个父类就是说自动加一个ACC——SUPER 0x0020

this_class

this_class的值必须对表中CONSTANT_Class_info类型结构体,这个结构体表示这个class文件所定义的类或者接口

super_class

super_class和this_class差不多 用来标识父的名称

这个值要么为0要么是CONSTANT_Class_info

如果这个值为0那么这个class文件只可能用表示Object类

如果是一个接口如果有super_class那么这个super_class必须是Object类的CONSTANT_Class_info

interfaces_count/interfaces[interfaces_count]

是用来表示类或者接口的直接父接口

父接口的表示由接口总数和接口组成数组

每个父接口元素为CONTANT_Class_info

他用来表示父接口  数组用来表示多个接口

fields_count/fields[fields_count]

表示类中定义的字段(非静态和静态的字段)

Filed_info结构

access_flags表示访问权限属性如上面小标题的access_flags的差不多

 name_index表示字段的名字

descriptor_index表示字段描述符的索引

attributes_count表示字段属性总数

attribute_info表示字段属性元素数组

适合字段属性分类有6种

class文件常量池中的fieldref_info类型是常量代表的是等号右边的字段的值

attribute_info属性分类:

1,ConstantValue:

表示静态变量的初始值static final修饰的 必须是值类型和string类型的(string类型不能new出来的)

 第一个是名称        第二个长度     第三个具体的数值

2,Synthetic

类成员没有在源文件中出现,由编译器自动产生的

3,Signature

泛型签名 

4,Deprecated

过时的字段

5,RuntimeVisibleAnnotations

使用的注解,并且运行时可见的注解(JVM可以反射读取)

注解定义是RetentionPolicy.RUNTIME的注解

6,RuntimeInvisibleAnnotations

使用的注解并且是运行时不可见注解(JVM不能反射读取到的)

注解定义是RetentionPolicy.CLASS的注解

CLASS是JVM不知道但是class文件知道的

注意点

注1,java接口中的基类是否为Object

任何接口是没有父类的 如果一个接口继承一个类那么会有三个常量池的CONSTANT_Class_info文件分别是:

他自己    Object   还有继承的类

我们假定在接口类中有一个Object obj = new Object();

那么在常量池中显示Object则正常       但是没有写Object

实际上在接口中会隐式的去实现Object的方法 但Object不是接口的基类 而是它的引用

注2,静态块,实例块,构造方法的实行顺序先执行静态块再实例块接着是构造方法

注3注解生命周期

RetentionPolicy.SOURCE——此注解类型的信息只会记录在源文件中,不会在class文件中

RetentionPolicy.CLASS——编译器将注解记录在class文件中,但无法加载到JVM中不会被反射读取

RetentionPolicy.RUNTIME——编译器将记录在class文件中并且加载到JVM,可以被反射读取到

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值