<JVM中篇:字节码与类的加载篇>01-Class字节码文件结构
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机)
同步更新:https://gitee.com/vectorx/NOTE_JVM
Class文件结构
1. Class字节码文件结构
| 类型 | 名称 | 说明 | 长度 | 数量 | |
|---|---|---|---|---|---|
| 魔数 | u4 | magic | 魔数,识别Class文件格式 | 4个字节 | 1 |
| 版本号 | u2 | minor_version | 副版本号(小版本) | 2个字节 | 1 |
| u2 | major_version | 主版本号(大版本) | 2个字节 | 1 | |
| 常量池集合 | u2 | constant_pool_count | 常量池计数器 | 2个字节 | 1 |
| cp_info | constant_pool | 常量池表 | n个字节 | constant_pool_count - 1 | |
| 访问标识 | u2 | access_flags | 访问标识 | 2个字节 | 1 |
| 索引集合 | u2 | this_class | 类索引 | 2个字节 | 1 |
| u2 | super_class | 父类索引 | 2个字节 | 1 | |
| u2 | interfaces_count | 接口计数器 | 2个字节 | 1 | |
| u2 | interfaces | 接口索引集合 | 2个字节 | interfaces_count | |
| 字段表集合 | u2 | fields_count | 字段计数器 | 2个字节 | 1 |
| field_info | fields | 字段表 | n个字节 | fields_count | |
| 方法表集合 | u2 | methods_count | 方法计数器 | 2个字节 | 1 |
| method_info | methods | 方法表 | n个字节 | methods_count | |
| 属性表集合 | u2 | attributes_count | 属性计数器 | 2个字节 | 1 |
| attribute_info | attributes | 属性表 | n个字节 | attributes_count |
2. Class文件数据类型
| 数据类型 | 定义 | 说明 |
|---|---|---|
| 无符号数 | 无符号数可以用来描述数字、索引引用、数量值或按照utf-8编码构成的字符串值。 | 其中无符号数属于基本的数据类型。 以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节 |
| 表 | 表是由多个无符号数或其他表构成的复合数据结构。 | 所有的表都以“_info”结尾。 由于表没有固定长度,所以通常会在其前面加上个数说明。 |
3. 魔数

4. 文件版本号

4.1. Class文件版本号对应关系
| 主版本(十进制) | 副版本(十进制) | 编译器版本 |
|---|---|---|
| 45 | 3 | 1.1 |
| 46 | 0 | 1.2 |
| 47 | 0 | 1.3 |
| 48 | 0 | 1.4 |
| 49 | 0 | 1.5 |
| 50 | 0 | 1.6 |
| 51 | 0 | 1.7 |
| 52 | 0 | 1.8 |
| 53 | 0 | 1.9 |
| 54 | 0 | 1.10 |
| 55 | 0 | 1.11 |

5. 常量池集合

| 类型 | 名称 | 数量 |
|---|---|---|
| u2(无符号数) | constant_pool_count | 1 |
| cp_info(表) | constant_pool | constant_pool_count - 1 |

5.1. 常量池计数器

5.2. 常量池表

| 类型 | 标志(或标识) | 描述 |
|---|---|---|
| CONSTANT_Utf8_info | 1 | UTF-8编码的字符串 |
| CONSTANT_Integer_info | 3 | 整型字面量 |
| CONSTANT_Float_info | 4 | 浮点型字面量 |
| CONSTANT_Long_info | 5 | 长整型字面量 |
| CONSTANT_Double_info | 6 | 双精度浮点型字面量 |
| CONSTANT_Class_info | 7 | 类或接口的符号引用 |
| CONSTANT_String_info | 8 | 字符串类型字面量 |
| CONSTANT_Fieldref_info | 9 | 字段的符号引用 |
| CONSTANT_Methodref_info | 10 | 类中方法的符号引用 |
| CONSTANT_InterfaceMethodref_info | 11 | 接口中方法的符号引用 |
| CONSTANT_NameAndType_info | 12 | 字段或方法的符号引用 |
| CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |
| CONSTANT_MethodType_info | 16 | 标志方法类型 |
| CONSTANT_InvokeDynamic_info | 18 | 表示一个动态方法调用点 |

| 标志符 | 含义 |
|---|---|
| B | 基本数据类型byte |
| C | 基本数据类型char |
| D | 基本数据类型double |
| F | 基本数据类型float |
| I | 基本数据类型int |
| J | 基本数据类型long |
| S | 基本数据类型short |
| Z | 基本数据类型boolean |
| V | 代表void类型 |
| L | 对象类型,比如:Ljava/lang/Object; |
| [ | 数组类型,代表一维数组。比如:`double[][][] is [[[D |








6. 访问标志

| 标志名称 | 标志值 | 含义 |
|---|---|---|
| ACC_PUBLIC | 0x0001 | 标志为public类型 |
| ACC_FINAL | 0x0010 | 标志被声明为final,只有类可以设置 |
| ACC_SUPER | 0x0020 | 标志允许使用invokespecial字节码指令的新语义,JDK1.0.2之后编译出来的类的这个标志默认为真。(使用增强的方法调用父类方法) |
| ACC_INTERFACE | 0x0200 | 标志这是一个接口 |
| ACC_ABSTRACT | 0x0400 | 是否为abstract类型,对于接口或者抽象类来说,次标志值为真,其他类型为假 |
| ACC_SYNTHETIC | 0x1000 | 标志此类并非由用户代码产生(即:由编译器产生的类,没有源码对应) |
| ACC_ANNOTATION | 0x2000 | 标志这是一个注解 |
| ACC_ENUM | 0x4000 | 标志这是一个枚举 |


7. 类索引、父类索引、接口索引

| 长度 | 含义 |
|---|---|
| u2 | this_class |
| u2 | super_class |
| u2 | interfaces_count |
| u2 | interfaces[interfaces_count] |


8. 字段表集合

8.1. 字段计数器

| 标志名称 | 标志值 | 含义 | 数量 |
|---|---|---|---|
| u2 | access_flags | 访问标志 | 1 |
| u2 | name_index | 字段名索引 | 1 |
| u2 | descriptor_index | 描述符索引 | 1 |
| u2 | attributes_count | 属性计数器 | 1 |
| attribute_info | attributes | 属性集合 | attributes_count |
8.2. 字段表

| 标志名称 | 标志值 | 含义 |
|---|---|---|
| ACC_PUBLIC | 0x0001 | 字段是否为public |
| ACC_PRIVATE | 0x0002 | 字段是否为private |
| ACC_PROTECTED | 0x0004 | 字段是否为protected |
| ACC_STATIC | 0x0008 | 字段是否为static |
| ACC_FINAL | 0x0010 | 字段是否为final |
| ACC_VOLATILE | 0x0040 | 字段是否为volatile |
| ACC_TRANSTENT | 0x0080 | 字段是否为transient |
| ACC_SYNCHETIC | 0x1000 | 字段是否为由编译器自动产生 |
| ACC_ENUM | 0x4000 | 字段是否为enum |

| 标志符 | 含义 |
|---|---|
| B | 基本数据类型byte |
| C | 基本数据类型char |
| D | 基本数据类型double |
| F | 基本数据类型float |
| I | 基本数据类型int |
| J | 基本数据类型long |
| S | 基本数据类型short |
| Z | 基本数据类型boolean |
| V | 代表void类型 |
| L | 对象类型,比如:Ljava/lang/Object; |
| [ | 数组类型,代表一维数组。比如:`double[][][] is [[[D |

9. 方法表集合

9.1. 方法计数器

9.2. 方法表

| 标志名称 | 标志值 | 含义 | 数量 |
|---|---|---|---|
| u2 | access_flags | 访问标志 | 1 |
| u2 | name_index | 方法名索引 | 1 |
| u2 | descriptor_index | 描述符索引 | 1 |
| u2 | attributes_count | 属性计数器 | 1 |
| attribute_info | attributes | 属性集合 | attributes_count |

| 标志名称 | 标志值 | 含义 |
|---|---|---|
| ACC_PUBLIC | 0x0001 | public,方法可以从包外访问 |
| ACC_PRIVATE | 0x0002 | private,方法只能本类访问 |
| ACC_PROTECTED | 0x0004 | protected,方法在自身和子类可以访问 |
| ACC_STATIC | 0x0008 | static,静态方法 |
10. 属性表集合

10.1. 属性计数器

10.2. 属性表

| 类型 | 名称 | 数量 | 含义 |
|---|---|---|---|
| u2 | attribute_name_index | 1 | 属性名索引 |
| u4 | attribute_length | 1 | 属性长度 |
| u1 | info | attribute_length | 属性表 |

| 属性名称 | 使用位置 | 含义 |
|---|---|---|
| Code | 方法表 | Java代码编译成的字节码指令 |
| ConstantValue | 字段表 | final关键字定义的常量池 |
| Deprecated | 类,方法,字段表 | 被声明为deprecated的方法和字段 |
| Exceptions | 方法表 | 方法抛出的异常 |
| EnclosingMethod | 类文件 | 仅当一个类为局部类或者匿名类时才能拥有这个属性,这个属性用于标识这个类所在的外围方法 |
| InnerClass | 类文件 | 内部类列表 |
| LineNumberTable | Code属性 | Java源码的行号与字节码指令的对应关系 |
| LocalVariableTable | Code属性 | 方法的局部变量描述 |
| StackMapTable | Code属性 | JDK1.6中新增的属性,供新的类型检查检验器和处理目标方法的局部变量和操作数有所需要的类是否匹配 |
| Signature | 类,方法表,字段表 | 用于支持泛型情况下的方法签名 |
| SourceFile | 类文件 | 记录源文件名称 |
| SourceDebugExtension | 类文件 | 用于存储额外的调试信息 |
| Synthetic | 类,方法表,字段表 | 标志方法或字段为编译器自动生成的 |
| LocalVariableTypeTable | 类 | 是哟很难过特征签名代替描述符,是为了引入泛型语法之后能描述泛型参数化类型而添加 |
| RuntimeVisibleAnnotations | 类,方法表,字段表 | 为动态注解提供支持 |
| RuntimeInvisibleAnnotations | 类,方法表,字段表 | 用于指明哪些注解是运行时不可见的 |
| RuntimeVisibleParameterAnnotation | 方法表 | 作用与RuntimeVisibleAnnotations属性类似,只不过作用对象或方法 |
| RuntimeInvisibleParameterAnnotation | 方法表 | 作用与RuntimeInvisibleAnnotations属性类似,只不过作用对象或方法 |
| AnnotationDefault | 方法表 | 用于记录注解类元素的默认值 |
| BootstrapMethods | 类文件 | 用于保存invokeddynamic指令引用的引导方法限定符 |



| 类型 | 名称 | 数量 | 含义 |
|---|---|---|---|
| u2 | attribute_name_index | 1 | 属性名索引 |
| u4 | attribute_length | 1 | 属性长度 |
| u2 | max_stack | 1 | 操作数栈深度的最大值 |
| u2 | max_locals | 1 | 局部变量表所需的存续空间 |
| u4 | code_length | 1 | 字节码指令的长度 |
| u1 | code | code_lenth | 存储字节码指令 |
| u2 | exception_table_length | 1 | 异常表长度 |
| exception_info | exception_table | exception_length | 异常表 |
| u2 | attributes_count | 1 | 属性集合计数器 |
| attribute_info | attributes | attributes_count | 属性集合 |






<JVM中篇:字节码与类的加载篇>01-Class字节码文件结构的更多相关文章
- <JVM中篇:字节码与类的加载篇>02-字节码指令集
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- <JVM中篇:字节码与类的加载篇>03-类的加载过程(类的生命周期)详解
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- <JVM中篇:字节码与类的加载篇>04-再谈类的加载器
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- jvm系列一、java类的加载机制
一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...
- 深入了解java虚拟机(JVM) 第十一章 类的加载
一.类加载机制概述 虚拟机把描述类的数据从class文件加载到内存并对数据进行效验,解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制. 二.类加载的机制 类加载的过程 ...
- Day18 (一)类的加载器
一个运行时的Java虚拟机(JVM)负责运行一个Java程序. 当启动一个Java程序时,一个虚拟机实例诞生:当程序关闭退出,这个虚拟机实例也就随之消亡. 如果在同一台计算机上同时运行多个Java程序 ...
- Java类的加载的一个小问题
前言 之前写了一篇文章专门介绍了一下类的加载和对象的创建流程,然后收到了一个博友的疑问,觉得蛮好的,在这里和大家分享下. 博文地址:[Java基础]Java类的加载和对象创建流程的分析 疑问 类在加载 ...
- 05 flask源码剖析之配置加载
05 Flask源码之:配置加载 目录 05 Flask源码之:配置加载 1.加载配置文件 2.app.config源码分析 3.from_object源码分析 4. 总结 1.加载配置文件 from ...
- 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】
目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...
随机推荐
- FreeBSD 中文TTY控制台
freebsd新型终端VT,支持cjk,所以丢个字体进去,就能显示中文了1,首先你没有改过控制台程序,使用的是默认的,,2,最新版本,本说明是以freebsd12.1release字体格式为.fnt命 ...
- Python接口测试-保持登录状态
#coding:utf-8import requestsimport json#登录url ="https://passport.cnblogs.com/user/signin"h ...
- python基础学习之元组和字典的功能方法
什么是元组?(tuple) emmmmmm,这个没必要深究吧,就是一排'元素',一行 格式: a = (1,2,3,4,5,6,7,8,9)用小括号表示的,极为元组. 其有序,且不可更改,可以对比st ...
- 2019 南京网络赛 B super_log 【递归欧拉降幂】
一.题目 super_log 二.分析 公式很好推出来,就是$$a^{a^{a^{a^{...}}}}$$一共是$b$个$a$. 对于上式,由于指数太大,需要降幂,这里需要用到扩展欧拉定理: 用这个定 ...
- 使用Webpack构建多页面程序
使用webpack搭建单页面程序十分常见,但在实际开发中我们可能还会有开发多页面程序的需求,因此我研究了一下如何使用webpack搭建多页面程序. 原理 将每个页面所在的文件夹都看作是一个单独的单页面 ...
- python网络编程--TCP客户端的开发
#导入socket模块 2 import socket 3 #参数说明 4 """ 5 socket类的介绍 6 创建客户端socket对象 7 socket.socke ...
- CCPC-2020 黑龙江省赛——Let’s Get Married
题意:~~ 思路:题目给出的数字太少了,我们多写几个,就会发现每层最左边的值等于1.2*k(k+1) ,k代表层数,找规律发现如果一个点的坐标为2.(x,y)且|a|+|b|=k,id<=2*k ...
- kthread_worker和kthread_work机制
1.概述 在阅读内核源码时,可以看到kthread_worker.kthread_work两个数据结构配合内核线程创建函数一起使用的场景.刚开始看到这块时,比较困惑,紧接着仔细分析源码后,终于弄清楚了 ...
- Flutter原理简介
Flutter 是怎么运转的? 与用于构建移动应用程序的其他大多数框架不同,Flutter 是重写了一整套包括底层渲染逻辑和上层开发语言的完整解决方案.这样不仅可以保证视图渲染在 Android 和 ...
- kong更改日志格式
基于业务的需求,需要对网关层的日志进行适当定制,以满足使用kibana的制图. 对于kong的日志格式更改,可查看到的资料都过于繁琐,特此记录. 修改kong的日志格式 # ctl edit depl ...