<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 ...
 
随机推荐
- 双向链表及有关操作(C语言)
			
#include <stdio.h> #include <stdlib.h> /** * 含头节点双向链表定义及有关操作 */ //操作函数用到的状态码 #define TRU ...
 - JS获取时间日期常用方法
			
1 当前时间: new Date() 2 当前周: function getCurrentWeek() { var date = new Date() var beginDate = new Date ...
 - P4847 银河英雄传说V2 题解(Splay)
			
题目链接 P4847 银河英雄传说V2 解题思路 我天哪!!!\(splay\)在\(rotate\)的时候先\(upd(y)\)再\(upd(x)\)!!以后不能再因为这个\(WA\)一晚上了!!! ...
 - SHA算法摘要处理
			
byte[] input="sha".getBytes();//待做消息摘要算法的原始信息,可以是任意字符串 MessageDigest sha=MessageDigest.get ...
 - 【java框架】MyBatis-Plus(1)--MyBatis-Plus快速上手开发及核心功能体验
			
1.MyBatis-Plus入门开发及配置 1.1.MyBatis-Plus简介 MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变, ...
 - 2019 GDUT Rating Contest III : Problem E. Family Tree
			
题面: E. Family Tree Input file: standard input Output file: standard output Time limit: 1 second Memory ...
 - 都在讲Redis主从复制原理,我来讲实践总结
			
摘要:本文将演示主从复制如何配置.实现以及实现原理,Redis主从复制三大策略,全量复制.部分复制和立即复制. 本文分享自华为云社区<Redis主从复制实践总结>,原文作者:A梦多啦A . ...
 - Python基础之告警定义与告警抑制
			
技术背景 在前面一篇博客中我们介绍了在python中自定义异常以及异常的捕获.这里我们要介绍另外一种形式的用户提醒:告警.我们这里就不给出一些过于官方或者技术的定义了,在实际项目中的使用场景主要有这么 ...
 - vue中的.sync修饰符用法
			
在项目中接触到父组件传值给子组件的时候,想在子组件改变父组件传的值.(比如用于弹窗关闭) 但是正常来说,vue2是不允许子组件直接改父组件传进去的值的. 所以我们需要在子组件内定义自定义事件,通知父组 ...
 - (十六)Struts2的标签库
			
一.简介 Struts2的标签库使用OGNL为基础,大大简化了数据的输出,也提供了大量标签来生成页面效果,功能非常强大. 在早期的web应用开发中,jsp页面主要使用jsp脚本来控制输出.jsp页面嵌 ...