1、类加载器
(1)书写代码:
public static void main(String[] args) { ClassLoader classLoade=Test1.class.getClassLoader(); System.out.println(classLoade); }
sun.misc.Launcher$AppClassLoader@18b4aac2
(2)查看源码(sun.misc.Launcher):
public Launcher() { Launcher.ExtClassLoader var1; try { var1 = Launcher.ExtClassLoader.getExtClassLoader(); } catch (IOException var10) { throw new InternalError("Could not create extension class loader", var10); } try { this.loader = Launcher.AppClassLoader.getAppClassLoader(var1); } catch (IOException var9) { throw new InternalError("Could not create application class loader", var9); }
执行代码:
public static void main(String[] args) { ClassLoader classLoade=Test1.class.getClassLoader(); while(classLoade!=null){ System.out.println(classLoade.getParent()); } }
sun.misc.Launcher$ExtClassLoader@1b6d3586
所以,AppClassLoader的父类是ExtClassLoader,
(3)查看源码(ClassLoader):
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
锁保证了同时只能有一个可以LoadClass,同时保证了唯一性,首先检查是否被加载过了,如加载过了则直接返回(c!=null)。
if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); }
ExtClassLoader的父类是Bootstrap
启动(Bootstrap)类加载器:负责将JAVAHOME/lib下面的类库加载到内存中(比如rt,jar)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。
标准扩展(Extension)类加载器:负责将JAVA_HOME/jre/lib/ext或者由系统变量java.ext.dirs指定位置中的类库加载到内存中
应用程序(Application)类加载器:它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。由于这个类加载器是ClassLoader中的getSystemClassLoader)方法的返回值,因此一般称为系统(System)加载器
加载顺序:自顶向下
检测顺序:自底向上
(4)双亲委任机制
目的:安全
父类能加载的就不给子类加载
程序安全是JDK的事,文件安全是系统的事
程序员写了不安全的程序,JDK有责任不让它运行
(5)其它
判断两个对象是不是同一个对象:使用的是不是同一个类加载器