还不懂java类加载机制的,建议看下这份阿里技术官总结的笔记!

类加载机制

把class文件加载到内存,并对数据进行校验,准备,解析,初始化,形成可以被虚拟机直接使用的字节码

类加载的时机(触发类的初始化)

  • 使用new关键字实例化对象
  • 读取一个类的静态代码块
  • 使用java.lang.reflect包的方式对类进行反射调用

类加载过程

整个生命周期包括:加载、校验、准备、解析、初始化、使用和卸载7个阶段。

  1. 加载:通过一个类的全限定名来获取定义此类的二进制字节流,将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构,在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据的访问入口
  2. 校验:校验是连接阶段的第一步,这一阶段的目的是确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟自身的安全。
  3. 准备:准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法去中进行分配。这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。
  4. 解析:解析阶段是虚拟机将常量池内的符号(Class文件内的符号)引用替换为直接引用(指针)的过程。
  5. 初始化:初始化阶段是类加载过程的最后一步,开始执行类中定义的Java程序代码(字节码)。

加载

  • 通过全类名获取class文件的二进制字节流
  • 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
  • 生成一个代表该类的class对象,作为方法区这些数据的访问入口
    根据字节码在java堆中生成一个代表这个类的java.lang.Class对象

校验

  • 验证Class文件中二进制字节流符合虚拟机的要求,不会涉及到虚拟机的安全
  • 文件格式验证
  • 元数据验证
  • 字节码验证

准备

  • 为类变量分配内存空间和设置初始值的阶段
  • 为新生对象分配内存

为新生对象分配内存

  • 如果Java堆内存是规整连续的,采用“指针碰撞”的分配方式
  • 如果不是连续规整的,采用“空闲列表”分配方式

内存是否规整取决于垃圾收集器是否带有压缩整理功能

这个初始值和初始化阶段的赋值不同,这里指的是变量的默认初始值,如果是final修饰的变量,就是赋予代码里制定的初始值

解析

虚拟机将符号引用替换为直接引用的过程

符号引用 :符号引用以一组符号来描述所引用的目标。符号引用可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可,符号引用和虚拟机的布局无关。个人理解为:在编译的时候一个每个java类都会被编译成一个class文件,但在编译的时候虚拟机并不知道所引用类的地址,多以就用符号引用来代替,而在这个解析阶段就是为了把这个符号引用转化成为真正的地址的阶段。

直接引用 :直接引用和虚拟机的布局是相关的,不同的虚拟机对于相同的符号引用所翻译出来的直接引用一般是不同的。如果有了直接引用,那么直接引用的目标一定被加载到了内存中。

初始化

根据程序代码去初始化变量和其他资源,构造函数

类加载器

BootstrapLoader/负责加载系统类

注意一个很重要的问题,就是java在逻辑上并不存在BootstrapKloader的实体,因为它是c++编写的,所以打印其内容会是null

启动类加载器主要加载 jre/lib下的jar文件。

ExtClassLoader/负责加载扩展类//继承类和实现类

扩展类加载器主要加载 jre/lib/ext 下的jar文件。

AppClassLoader/负责加载应用类

应用程序类加载器主要加载 classpath 下的文件

Android类加载器

对于Android而言,最终的apk文件包含的是dex类型的文件,dex文件是将class文件重新打包,打包的规则又不是简单地压缩,而是完全对class文件内部的各种函数表,变量表进行优化,产生一个新的文件,即dex文件。因此加载这种特殊的Class文件就需要特殊的类加载器DexClassLoader。

双亲委派模型

当加载一个类时,会优先使用父类加载器加载,当父类加载器无法加载时才会使用子类加载器去加载。这么做的目的是为了避免类的重复加载

解释器

对字节码逐条解释执行,这种方式的执行速度相对会比较慢;重复执行需要重复解释

JIT(即时编译器)

在运行时,虚拟机将会把这些频繁调用的代码编译成与本地平台相关的机器码,并进行优化,可重复执行,缓存效率高

Class文件字节码结构

魔数—副版本号—主版本号—常量池计数器—常量池数据区—访问标志—类索引—父类索引—接口计数器—接口信息数据区—字段计数器—字段信息数据区—方法计数器—方法信息数据区—属性计数器—属性信息数据区

魔数:class文件的标志,确定这个文件是否为一个能被虚拟机接收的class文件

类B继承A,A、B两个类中都有静态变量、成员变量、静态代码块、构造方法执行顺序是什么?

1.父类【静态成员】和【静态代码块】,按在代码中出现的顺序依次执行。
2.子类【静态成员】和【静态代码块】,按在代码中出现的顺序依次执行。
3.父类的【普通成员变量被普通成员方法赋值】和【普通代码块】,按在代码中出现的顺序依次执行。
4.执行父类的构造方法。
5.子类的【普通成员变量被普通成员方法赋值】和【普通代码块】,按在代码中出现的顺序依次执行。
6.执行子类的构造方法。

JVM在搜索类的时候,又是如何判定两个class是相同的呢?

JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的。只有两者同时满足的情况下,JVM才认为这两个class是相同的。

就算两个class是同一份class字节码,如果被两个不同的ClassLoader实例所加载,JVM也会认为它们是两个不同class。

类的加载过程,Person person = new Person();为例进行说明。

1).因为new用到了Person.class,所以会先找到Person.class文件,并加载到内存中;
2).执行该类中的static代码块,如果有的话,给Person.class类进行初始化;
3).在堆内存中开辟空间分配内存地址;
4).在堆内存中建立对象的特有属性,并进行默认初始化;
5).对属性进行显示初始化;
6).对对象进行构造代码块初始化;
7).对对象进行与之对应的构造函数进行初始化;
8).将内存地址付给栈内存中的p变量

class实例和class对象的区别

java有两种对象:实例对象和Class对象。
每个类的运行时的类型信息就是用Class对象表示的。它包含了与类有关的信息。
其实我们的实例对象就通过Class对象来创建的

有三种获得Class对象的方式:

  • Class.forName(“类的全限定名”)
  • 实例对象.getClass()
  • 类名.class (类字面常量)

实例newInstance()

最后

看完有什么不懂的可以在评论区问我,觉得对你有帮助的话记得给我点个赞!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343