Java基础:类文件结构及类加载
Class文件结构
- 魔数 4bits 确定该文件是否是可接受的Class文件(0xCAFEBABE)
- 版本号 4bits 包括次版本号和主版本号
- 常量池 包括字面量(文本字符串,声明为final的常量值)和符号引用(类和接口的全限定名,字段的名称和描述符,方法的名称和描述符)
- 访问标志 2bits 标志识别类或者接口层次的访问信息,如类是否为public,是否为abstract,是否为final,是Class还是Interface。
- 类索引 父索引与接口索引集合 用于确定这个类的继承关系
- 字段表集合 包括用于描述接口或类中声明得变量,包括public private protected static final volatile transient synthetic(字段是否为编译器自动产生) enum,以及变量简要名称和类型描述符(基本类型,数组)。
- 方法表集合 类似字段表集合,包括前缀,简要名称,类型描述符,不包含方法中的代码。
- 属性表 存放多种属性,如方法中的代码存在Code属性中,操作栈深度最大值,exception等。
类加载机制
类加载的整个生命周期: 加载,验证,准备,解析,初始化,使用,卸载
对类初始化的情况
- new关键字实例化对象,读取设置类的静态字段(非final修饰),调用一个类的静态方法
- 反射调用
- 初始化一个类时,若父类没有初始化,则先初始化父类
- 虚拟机启动时,用户指定的主类
- java.lang.invoke.MethodHandle的解析结果是一个静态方法,则需要先初始化方法对应的类
加载
- 通过一个类的全限定名来获取定义此类的二进制字节流。
- 将字节流代表的静态存储结构转化为方法区的运行时结构。
- 内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据访问入口。
验证
- 文件格式验证:对Class文件进行格式校验。是否以魔数开头,主次版本号是否可处理,常量池中常量是否全支持...
- 元数据验证:对字节码描述的信息进行语义分析。这个类是否有父类,父类是否不允许继承,字段是否与父类矛盾...
- 字节码验证:对数据流和控制流进行分析。对方法体进行校验分析,如类型校验等。
- 符号引用验证:对符号引用进行校验保证其可转换为直接引用。
准备
- 为变量分配内存。(仅包含类变量,不包括实例变量)
- 为变量设置初始值。(仅设置类型对应的默认值,不赋值)
解析
解析阶段虚拟机将常量池内的符号引用替换为直接引用。
符号引用用一组符号描述所引用的目标,使用时可以无歧义的定位到目标。
直接引用可以是直接指向目标的指针,相对偏移量,或能够间接定位到目标的句柄。不通虚拟机中翻译出的直接引用一般不同。
初始化
初始化是类加载过程中最后一步。初始化接端是执行类构造器<clinit>()方法的过程。该方法是编译器自动收集类中所有类变量的赋值动作和静态语块(static{})中的语句合并而成的,其收集顺序取决于源文件中的出现顺序。虚拟机会保证子类的<clinit>()执行前,父类的<clinit>()已经执行过,因此不需要显示的调用。多线程环境中,<clinit>()方法使用悲观锁阻塞,并保证只被运行一次。
类加载器
上述过程中,第一步加载中,通过一个类的全限定名来获取描述此类的二进制字节流这个机制放在Java虚拟机外部实现,实现这个动作的代码模块称为类加载器。任意一个类,都需要由它的加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器都拥有一个独立的类命名空间。两个类是否相等,只在这两个类是由同一个类加载器加载的前提下才有意义,否则必顶步等。(相等指equals()方法,instanceof关键字等)
双亲委派模型
从JVM角度,只存在两种不同的类加载器:启动类加载器,C++实现,JVM一部分;其他类加载器,Java实现,独立于类,继承java.lang.ClassLoader。
启动类加载器负责将\lib中JVM识别的类库加到JVM内存中(如名字为rt.jar),启动类加载器无法被Java程序直接引用,用户自定义加载器时,把加载请求委派给引导类加载器只需要使用null替换。
其他类加载器包括扩展类加载器和应用程序类加载器,前者负责加载\lib\ext目录中的类库,后者是ClassLoader::getSystemClassLoader()的返回值,负责加载用户类路径上指定的类库,没有自定义过类加载器,这个加载器就是程序中默认的加载器。
这些加载器的关系如图所示

双亲委派模式要求除了顶层的启动类加载器,其余的类加载器都应该有自己的父加载器。其工作过程中,如果一个类加载器收到了类加载的请求,它首先不回去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层级的加载器都是如此,因此所有的加载请求最终都应该传到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。该模式保证了Java程序中的稳定性,如,重写rt.jar类中的类,不会有编译错误,但无法被加载。
双亲委派模型不是强制性约束模型,由于它的某些缺陷(如基础类要调用回用户的代码),某些标准服务打破了它,如JNDI服务,用于对资源进行集中管理和查找,JNDI使用了线程上下文类加载器。Java中所有涉及SPI的加载动作都采用这种方式,如JDBC。另外,模块热部署也破坏了双亲委派模型。
Java基础:类文件结构及类加载的更多相关文章
- 深入理解java虚拟机【Java Class类文件结构】
Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码 ...
- (转)《深入理解java虚拟机》学习笔记5——Java Class类文件结构
Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码 ...
- 第31节:Java基础-类与对象
前言 Java基础-类与对象,方法的重载,构造方法的重载,static关键字,main()方法,this关键字,包,访问权限,类的继承,继承性,方法的重写,super变量. 方法的重载:成员方法的重载 ...
- 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制
第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- Class类文件结构、类加载机制以及字节码执行
一.Class类文件结构 Class类文件严格按照顺序紧凑的排列,由无符号数和表构成,表是由多个无符号数或其他数据项构成的符合数据结构. Class类文件格式按如下顺序排列: 类型 名称 数量 u ...
- Java虚拟机-类文件结构
目录 类文件结构 Class类文件的结构 魔数与Class文件的版本 常量池 访问标志 类索引.父类索引和接口索引集合 字段表集合 方法表集合 属性表集合 完整结构描述 实例 源码 Class文件 分 ...
- JAVA基础知识之JVM-——自定义类加载器
JVM中除了根加载器之外其他加载器都是ClassLoader的子类实例, 可以通过扩展ClassLoader的子类,通过重写方法来实现自定义的类加载器. ClassLoader中有两个关键的方法如下, ...
- jvm虚拟机笔记<三> 类文件结构与类加载机制
java虚拟机具有语言无关系,它只和“class文件“这种特定的二进制文件格式绑定. 不同语言的编译器将对应的程序编译成字节码文件(*.class),送给jvm执行. class文件本质上就是一张表, ...
随机推荐
- java书籍推荐[转]
作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.下面就按照学习顺序,给大家推荐下面这些JAVA书籍.一.Java编程入门类,选择大于努力,入门太重要.对 ...
- C静态库和动态库的制作
(一)静态库就是把一些*.o的文件集合起来:以*.a结尾打包:做成的lib库文件:专门放到lib目录下 静态库的制作: 1.制作*.a文件 把之前src/mymath.c 的源文件 编译成单独的o文件 ...
- Problem 7 树状数组+转化
$des$有一棵 $n$ 个点的以 $1$ 为根的树, 以及 $n$ 个整数变量 $x_i$ .树上 $i$ 的父亲是 $f_i$ ,每条边 $(i,f_i)$ 有一 个权值 $w_i$ ,表示一个方 ...
- Codeforces Round #607 (Div. 2)
A - Suffix Three 题意:规定三种语言的结尾符,给出字符串,判断是什么语言. void test_case() { string s; cin >> s; reverse(s ...
- element ui的table的头部自定义
<el-table-column label="级别" min-width="120" prop="clueLevel" align= ...
- bugku web所有writeup_超详细讲解_持续更新
首先说一下我的主用工具,在windows下,主要是用这些,用到其他特定的工具会在题里说. 0.浏览器:火狐,配合Max hackbar插件 (这个是免费的) 1.抓包改包:burpsuite.http ...
- certification on windows and
https://jingyan.baidu.com/article/335530dae0eb2319ca41c378.html
- Fiddler查看request是由哪一个process发起的
有一个Process列 查看到进程编号是24836 然后用chrome自带的TaskManager查看对应的是哪一个进程 https://www.lifewire.com/google-chrome- ...
- Visual Studio、.NET Framework、VC++、C#各个版本的对应关系
Visual Studio..NET Framework.VC++.C#各个版本的对应关系 Visual Studio版本 .NET Framework版本 内部版本 VC++版本 C#版本 Visu ...
- Java开发手册-编程规约精选
# Java开发手册-编程规约精选 ## 总约 - 采用驼峰写法 ## 变量 - 首字母小写 ## 方法 - 方法名首字母小写- 参数首字母小写 ## 引用 - <阿里巴巴Java开发手册> ...