Java类加载机制

类从被加载到内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用、卸载。

几种触发类的初始化的场景(加载、验证等自然发生在初始化之前):
1. 遇到new,getstatic, putstatic, invokestatic这4条字节码指令时。具体场景指使用new关键字实例化对象时、读取或设置一个静态字段(被final修饰、已在编译器把结果放入常量池的静态字段除外)、调用一个类的静态方法时。
2. 使用java.lang.reflect包的方法对类进行反射调用时。
3. 当初始化一个类时,如果发现其父类还没有初始化,则需要先触发其父类的初始化。
4. 当虚拟机启动时,用户需要制定一个要执行的主类,虚拟机会先初始化这个类。

类加载的全过程

加载——>链接(验证/准备/解析)——>初始化

加载

  • 通过一个类的全限定名来获取定义此类的二进制字节流;
  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
  • 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

验证

文件格式验证、元数据验证、字节码验证、符号引用验证

准备

正式为类变量(被static修饰的变量)分配内存,并设置类变量系统初始值(数据类型的零值)的阶段。这些变量所使用的内存都将在方法区中进行分配。

解析

将常量池内的符号引用替换为直接引用的过程,包括类或接口的解析、字段解析、类方法解析、接口方法解析。

初始化

初始化阶段是执行类构造器()方法的过程,它区别于实例构造器()方法。
()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的。
父类先于子类进行初始化。

类加载器

类加载器,负责实现“通过一个类的全限定名来获取描述此类的二进制字节流”的代码模块。每一个类加载器,都有一个独立的类名称空间,对于任意一个类,都要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性。
常用的类加载器:
1. 启动类加载器(Bootstrap ClassLoader):负责加载\lib目录中的类库。
2. 扩展类加载器(Extension ClassLoader):负责加载\lib\ext目录中的类库。
3. 应用程序加载器(Application ClassLoader):负责加载用户类路径上所指定的类库,也叫系统类加载器。
类加载器的双亲委派模型:
双亲委托机制

某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
意义:防止内存中多次出现同样的字节码(避免多次加载)。

Others

Human man = new Woman();  //Woman extends Human
//静态类型:Human
//实际类型:Woman  

静态分派: 所有依赖静态类型来定位方法执行版本的分派动作称为静态分派,其典型应用是方法重载(根据参数的静态类型来定位目标方法)。静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机执行的。 (属于多分派类型,根据静态类型和方法参数进行选择)
动态分派:在运行期根据实际类型确定方法执行版本,它与重写(Override)有很大的而关联。(单分派类型,只考虑方法的接受者的实际类型)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值