文章目录
1 类加载器分类
- jvm包含两种类型的类加载器,分别为 引导类加载器(bootstrap classloader) 和 自定义加载器
如果一个类型时由用户加载器进行加载的,那么jvm会将这个类加载器的一个引用作为类型信息的一部分保存在方法区中
- 自定义加载器是 所有派生于抽象类classloader的类加载器(包括系统加载器,扩展加载器)
对于用户自定义的类,默认使用的是系统类加载器进行加载而java的核心类库都是使用的引导类加载器
public class Test4 {
public static void main(String[] args) {
//系统类加载器
ClassLoader classLoader = Test4.class.getClassLoader();
System.out.println(classLoader);
//引导类加载器
ClassLoader classLoader1 = String.class.getClassLoader();
System.out.println(classLoader1);
}
}
1.1启动类加载器
-
这个类使用的是 c/c++语言实现
-
用来加载java的核心类库,用于提供jvm自身所需要的类
-
并不继承java.lang.Classloader
-
加载扩展类和应用程序类,并指定为他们的父类加载器
-
处于安全考虑,BootStrap启动类加载器只加载包名为java、javax、sun等开头的类
1.2扩展类加载器
-
java语言编写
-
派生于classLoader
-
父类加载器为启动类加载器
-
从java.ext.dirs系统属性所指定的目录加载 或从jdk安装目录jre/lib/ext子目录下加载,用于创建的jar包方在此目录下,也会自动由扩展类加载
1.3系统类加载器
-
java语言编写
-
派生于classLoader
-
父类加载器为扩展类加载器
-
该类是程序中默认的类加载器
1.4为什么要自定义类加载器
-
隔离加载类
-
修改类加载的方式
-
扩展加载源
-
防止源码泄露
2双亲委派机制
java虚拟机对class文件采用的是按需加载的方式,当需要使用该类时才会将class文件加载到内存,而且加载某类的class文件是,java虚拟机采用的是双亲委派机制,把请求交由父类处理。
2.1工作原理
-
如果类加载器收到了类加载的请求,它不会自己先去加载,而是把这个请求委托给父类加载器(最终直到 启动类加载器)
-
如果父类加载器可以完成加载任务,就直接返回,无法完成的话,子加载器才会自己尝试。
优势:避免类的重复加载,保护程序安全,防止核心api被篡改
2.2沙箱安全机制
自定义string类时,在加载的时候,会使用双亲委派机制到启动类加载器去加载jdk自带的文件(rt.jar包中的string类),这样就可以保证对java核心源代码的保护,这就是沙箱安全机制
3类的主动使用与被动使用
3.1jvm中表示class对象是否为同一对象的条件
-
全限定名相同
-
类加载器classloader也必须相同
也就是说类所要保证相同,不仅仅需要来源于同一个class文件,他们的classLoader的实例对象也要相同
3.2主动使用
-
创建类的实例
-
访问某个类的或接口的静态变量,或者对改静态变量赋值
-
调用类的静态方法
-
反射
-
初始化一个类的子类
-
jvm启动时被标明为启动类的类
-
jdk7依赖提供的动态语言支持
除上面七种以外都是类的被动使用,主动使用与被动使用的区别在于 是否导致类的初始化(被动使用不会导致类的初始化)