3.2 类的构造器
1. <clinit>() 和 类的构造器 不是一回事
2. 构造器是虚拟机视角下的 <init>方法
- 无参构造器
- 带参构造器
四、类加载器分类
- 按照JVM规范定义
1. 引导类加载器(Bootstrap ClassLoader)
- 只负责加载系统的核心类库,用于提供JVM自身的类(如String类)
- 使用c,c++来实现的, 并不继承ClassLoader,没有父类加载器
- 嵌套在JVM 里面的
- 负责加载平台类加载器和系统类加载器(因为他们也是对象啊),同时指定为他们的父类加载器
- 出于安全考虑,只加载包名为 java javax sun开头的类
- 一个JVM里面只会有一个,打印的时候为null
2. 自定义类加载器(User-Defined ClassLoader)
- 派生于抽象类ClassLoader的类加载器
- 并不是说程序员自定义的类加载器
- 使用java语言实现的
- 父类加载器为BootstrapClassLoader(父类的意思是:你是由我来加载的, 通过getParent)
2.1 PlatformClassLoader(平台类类加载器)
- jdk.internal.loader.ClassLoaders$PlatformClassLoader来实现
- 从java指定目录下加载jar包(不是核心库,用户文件如果放在该目录,也会被该类加载)
2.2 AppClassLoader(系统类类加载器)
- jdk.internal.loader.ClassLoaders$AppClassLoader实现
- 负责加载环境变量classpath或系统属性
- 程序中默认类加载器(也就是用户写的类)
- 通过ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader()获取到类加载器
2.3 用户自定义类加载器
- java的日常开发中,类的加载几乎都是通过上面三种类加载器相互配合执行
- 必要时候,我们还可以自定义类加载器
1. 隔离加载类
2. 扩展加载源:比如从磁盘中读取一个类的.class
3. 修改类的加载方式
4. 防止源码泄漏:比如编译的时候加密了,那么加载的时候就需要解密
## 1. 自定义的流程
1. 继承抽象类java.class.lang.ClassLoader类的方式
2. findClass(): 具体的逻辑
如果没有复杂需求,直接继承URLClassLoader即可
package com.nike.erick.d05;
public class MultiThread {
/*从SystemClassLoader => PlatformClassLoader => BootStrapClassLoader*/
public static void main(String[] args) {
/*引导类 类加载器: Bootstrap class loader*/
ClassLoader stringClassLoader = String.class.getClassLoader();
System.out.println(stringClassLoader);
/* 系统类类加载器: AppClassLoader*/
/*jdk.internal.loader.ClassLoaders$AppClassLoader@2c13da15*/
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
/*平台类类加载器:PlatformClassLoader*/
/*jdk.internal.loader.ClassLoaders$PlatformClassLoader@5a39699c*/
ClassLoader platformClassLoader = systemClassLoader.getParent();
System.out.println(platformClassLoader);
/*null*/
ClassLoader bootstrapClassLoader = platformClassLoader.getParent();
System.out.println(bootstrapClassLoader);
/*用户自定义的类 的类加载器
1. jdk.internal.loader.ClassLoaders$AppClassLoader@2c13da15
2. 系统类的类加载器,一个JVM中只会存在一个*/
ClassLoader erickClassLoader = MultiThread.class.getClassLoader();
System.out.println(erickClassLoader);
}
}
五、双亲委派机制
1. 案列
2. 原理
- JVM对Class文件采用 按需加载的方式,懒加载
- 加载时候用的是双亲委派机制,即把请求交给父类处理
2.1 不能加载
3. 优点
- 避免类被重复加载
- 保护程序安全,防止核心API被随意篡改