Java类加载相关知识

类加载的委托机制

类的加载一般会联系到三种类加载器(以下内容不涉及到自定义加载器):
BootstrapClassLoader
ExtendedClassLoader
AppClassLoader(又叫SystemClassLoader)
从上到下这三个加载器类是父子关系。

当运行一个程序的时候,总是由AppClassLoader开始加载指定的类,在加载类时,每个类的加载首先都会上交给父类,父类尝试加载,如果父类找不到对应的类信息,则再由子类加载。

换句话说,某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。

那么什么样的累会被这三种加载器加载呢?

启动(Bootstrap)类加载器:
是用本地代码实现的类装入器,将/lib下面的类库加载到内存中(比如rt.jar)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

标准扩展(Extension)类加载器:
是由 Sun ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将< Java_Runtime_Home >/lib/ext或者由系统变量 java.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。

系统(System)类加载器:
是由 Sun 的 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。开发者可以直接使用系统类加载器。

委托机制具体含义

当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?

首先当前线程的类加载器去加载线程中的第一个类(假设为类A)。
注:当前线程的类加载器可以通过Thread类的getContextClassLoader()获得,也可以通过setContextClassLoader()自己设置类加载器。
如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器去加载类B。
还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
委托机制的意义 — 防止内存中出现多份同样的字节码
比如两个类A和类B都要加载System类:

如果不用委托而是自己加载自己的,那么类A就会加载一份System字节码,然后类B又会加载一份System字节码,这样内存中就出现了两份System字节码。
如果使用委托机制,会递归的向父类查找,也就是首选用Bootstrap尝试加载,如果找不到再向下。这里的System就能在Bootstrap中找到然后加载,如果此时类B也要加载System,也从Bootstrap开始,此时Bootstrap发现已经加载过了System那么直接返回内存中的System即可而不需要重新加载,这样内存中就只有一份System的字节码了。

new一个对象(没有继承其他类的对象)的时候发生了什么

从类被加载到其对象实例化完成,总共经历了三个步骤:
加载、连接(细分为验证、准备、解析)、初始化

加载的过程主要是将类加载到方法区

紧随而来的是连接阶段,将类中的static变量(即类变量)和static方法都会被加载到方法区中的静态区,对于类属性(static修饰的属性)而言,它们的初始化也在此时确定,静态代码块 在此时执行且仅执行一次。虚拟机将为新生对象在上分配内存。这个任务等同于将一块确定大小的内存从java堆中划分出来。将分配到的内存空间都初始化为零值(类型对应的零值见下表),同时对对象进行必要的设置(GC年龄、对象哈希码、对应着哪个类的实例等)并将该内存区域的地址赋给栈上的变量。直到此时,虚拟机意义上的对象就创建好了。

数据类型零值数据类型零值
int0booleanfalse
long0Lfloat0.0f
short(short)0double0.0d
char‘\u0000’referencenull
byte(byte)0

但是,这个“对象”并不能使用,因为没有进行初始化,它的所有对象属性都是零值(类属性已经在前面阶段初始化好了),实例化过程刚刚走完了2/3(或4/5)。最后,通过构造器或构造代码块进行实例初始化。

对于有父类的类是如何加载的(分层加载)

对于有父类的子类加载的过程中,首先加载父类,然后再加载子类,即所谓的分层加载。(待续)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值