点击关注公众号,干货第一时间送达

“人生当中,成功只是一时的,失败却是主旋律。
但是如何面对失败,却把人分成了不同的样子。
有的人会被失败击垮,有的人能够不断地爬起来继续向前。
我想真正的成熟应该并不是追求完美,而是直面自己的缺憾。
这才是生活的本质。”
卡塔尔世界杯1\8决赛的最后,因为点球大战的失误,巴西队折戟于此。
而内马尔泪洒现场,令所有人都为之动容。
我相信,最后的桑巴舞者,一定会再起征程!
生活就是如此,无畏地继续向前!
Ok,咱们回到本文。
之前的文章:类的生命周期 之 加载(Loading)、类的生命周期 之 链接(Linking)、类的生命周期 之 初始化(Initialization)
小编给各位介绍了类的生命周期重要的三个环节。
今天呢,要带大家看看另一个值得关注的点,类加载器(ClassLoader)
一,类加载器(ClassLoader)概述
ClassLoader的作用:
ClassLoader是Java的核心组件,所有的Class都是由ClassLoader进行加载的,ClassLoader负责通过各种方式将Class信息的二进制数据流读入JVM内部,转换为一个与目标类对应的java.lang.Class对象实例。然后交给JVM进行链接、初始化等操作。因此,ClassLoader在整个装载阶段,只能影响到类的加载,而无法通过ClassLoader去改变类的链接和初始化行为。至于它是否可以运行,则由Execution Engine决定。
翻译一下,如下图所示:

1,类的加载分类
class文件的显式加载和隐式加载指:JVM加载class文件到内存的方式。
显式加载:在代码中通过调用ClassLoader加载class对象。比如Class.forName,
或者 this.getClass().getClassLoader().loadClass() 加载class对象
隐式加载:不直接在代码中调用ClassLoader方法加载class对象,而是通过JVM自动加载到内存。比如在加载某个类的class文件时,该类的class文件中引用了另外一个类的对象,此时额外引用的类将通过JVM自动加载到内存中
如下图所示,两种方式都是显示加载:
public class PassiveUseTest {
@Test
public void test4(){
try {
//方式1
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class aClass = loader.loadClass("com.pipickeke.boot.test.Father");
System.out.println(aClass);
//方式2
Class aClass1 = Class.forName("com.pipickeke.boot.test.Father");
System.out.println(aClass1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Father{
public static int num = 1;
static {
System.out.println("Father 初始化");
}
}
2,命名空间 和 类的唯一性
类的唯一性:
对于任意一个类,都需要由加载它的类加载器和这个类本身一同确认其在JVM中的唯一性。每一个类加载器,都用于一个独立的类名称空间:比较两个类是否相等,只有在这两个类是由同一个类加载器加载的前提下才有意义。否则,即便这两个类源自同一个Class文件,被同一个JVM加载,只要加载他们的类加载器不同,那么这两个类就必定不同。
命名空间:
1,每个类加载器都有自己的命名空间,命名空间由该类加载器及所有父类加载器所加载的类组成。
2,在同一命名空间中,不会出现类的完整名字相同的两个类。
3,在不同的命名空间,有可能出现类的完整名称。
3,类加载器机制的三个基本特征
双亲委派模型。但不是所有类加载器都遵循这个模型
可见性。子加载器可以访问父加载器加载的类型,但是反过来是不允许的。不然,因为缺少必要的隔离,我们就没有办法利用类加载器去实现容器的逻辑。
单一性。由于父加载器的类型对于子加载器是可见的,所以父加载器中加载过的类型,就不会在子加载器重复加载。但是注意,类加载器“邻居”间,同一类型仍然可以被加载多次,因为互相并不可见。
记住了没?
今天的内容比较简单,记忆一下即可。





