1、系统装载class文件
(1)verification :校验 是否符合Class规范,CAFE BABE..
(2)preparation :准备 静态变量赋默认值的阶段
(3)resolution :解析 class常量池中的符号引用变为直接地址引用
2、类加载器
3、双亲委派机制
(1)Bootstrap是C++实现的,Java中并没有一个类与之对应,所以返回null
(2)classloader的classloader是Bootstrap加载的 最后两行输出null
(3)每个加载器都会有自己的缓存,缓存中查不到才会去提交给父加载器
为什么要使用双亲委派机制?
(1)保证安全,防止核心库被篡改
(2)资源重复利用,上面已经加载过了,不需要二次加载了。
4、如何自定义类加载器
(1)继承ClassLoader
(2)重写模板方法findClass
- 调用defineClass
(3)自定义类加载器加载自加密的class
- 防止反编译
- 防止篡改
什么时候需要去加载一个类?
- Spring热部署
什么时候用过模板方法?
- 自定义类加载器的时候,需要重写findClass,其他的都已经实现好了,直接嵌入实现就可以了。
什么时候回使用到自定义Classloader?
- Java的.class文件很容易被反编译,我可以定义自己的格式,不想被别人反编译,可以通过自定义Classloader来进行保护数据。比如期间将密码password进行加密。
- 当我自己想要加载的时候,可以在findclass中读出来,再进行自定义解析,就可以拿到原值。
系统默认的ClassLoader是APPClassloader
5、如何打破双亲委派机制?
重写loadeClass()即可
何时打破过?
- jdk1.2之前,自定义ClassLoader都必须重写loadClass()
- 在线程里面,可以设定线程上下文的ClassLoader
- 热部署的时候tomcat有自己的模块可以指定ClasLoader(可以加载同一类库的不同版本,比如:加载两个项目,一个Junit5,一个Junit4,tomcat不会加载到同一空间,因为如果判断如果已经加载过,另一个就不会加载了)
- loadClass的逻辑是判断是否加载过,我们重写之后不判断是否加载过,直接加载。
6、类加载面试题
分析:
- 1.赋默认值 count 0 T null
- 2.赋初始值 count 2 T 调用构造方法 count++ ,count变为3
分析:
- 1.赋默认值 T null count 0
- 2.赋初始值 T 调用构造方法 count变为1 count赋初始值变为2
注: 静态变量是在类加载的时候分为两步,赋默认值赋初始值
成员变量是在new对象的时候分为两步,赋默认值赋初始值