类加载器一共有三种:
BootstrapClassLoader(根加载器)
c++
编写,加载java
核心库 java.*
,构造ExtClassLoader
和AppClassLoader
。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作
ExtClassLoader (标准扩展类加载器)
java
编写,加载扩展库,如classpath
中的jre
,javax.*
或者
java.ext.dir
指定位置中的类,开发者可以直接使用标准扩展类加载器。
AppClassLoader(应用类加载器)
java`编写,加载程序所在的目录,如`user.dir`所在的位置的`class
我们可以通过getParent()查看
package com.li;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Main main = new Main();
System.out.println("系统类加载器=>"+main.getClass().getClassLoader());
System.out.println("扩展类加载器=>"+main.getClass().getClassLoader().getParent());
System.out.println("根加载器=>"+main.getClass().getClassLoader().getParent().getParent());
}
}
运行结果:
双亲委派机制
比如自己创建一个java.lang.String类
package java.lang;
public class String {
public String to(){
return "aa";
}
public static void main(String[] args) {
String s = new String();
ClassLoader classLoader = s.getClass().getClassLoader();
System.out.println(classLoader);
}
}
运行结果:
总结:
这因为有双亲委派机制来保护java的安全性。
双亲委派机制会先去找上一层的父加载器:系统类加载器 => 控制类加载器 => 根加载器
先去找根加载器,如果根加载器 没有找到就去找控制类加载器,最后才是的系统类加载器 。