-
loading
class文件 从硬盘 加载到 内存。 -
linking
1. verification 校验。检查满不满足class文件的格式。 2. preparation 将 静态变量 赋默认值。默认值是0。 3. resolution 将 常量池中的 符号引用 转换成 直接可以访问的内存地址。
-
initializing
静态变量 赋 初始值。调用静态代码块。
一个class文件 被加载到内存后,在内存有两份东西。一份是class二进制字节码本身,另一份是这个类的class对象。
别的类要调用它的时候,首先会找到它的class对象,然后通过class对象访问class字节码。
class文件是按需加载进内存的。
在加载一个类的时候:
- JVM 先委托 CustomClassLoader 在自己的缓存里找,看有没有加载过这个类,
- CustomClassLoader 的缓存里 如果有这个类,返回,如果没有,委托给自己的上一层类加载器 AppClassLoader,
- AppClassLoader 如果发现 自己加载过这个类,返回,如果没有,就会委托自己的上一层类加载器 ExtClassLoader,
- ExtClassLoader 如果发现 自己加载过这个类,返回,如果没有,就会委托自己的上一层类加载器 Bootstrap,
- Bootstrap 如果发现 自己加载过这个类,返回,如果没有,
- Bootstrap就去自己的管辖 rt.jar、charset.jar … 里找,如果有,返回,如果没有,再往回委托给 ExtClassLoader,
- ExtClassLoader 就去自己的管辖 jre/lib/ext/*.jar … 里找,如果有,返回,如果没有,再往下委托给 AppClassLoader,
- AppClassLoader 就去自己的管辖 classpath 里找,如果有,返回,如果没有,再往下委托给 CustomClassLoader。
- 最终如果 CustomClassLoader 从自己的管辖 能够加载到这个类,成功返回,如果没有加载到,抛异常ClassNotFound。
双亲委派这个词起的不是特别好,与双亲(父和母)没有关系。它所指的双亲委派,是一个从子到父,又由一个从父到子的过程。查找 已加载缓存 的时候 从子到父,查找 自己加载管辖并实际加载 的时候 从父到子。
为什么要采用这个机制呢?怪折腾的。
主要是为了安全。
classLoader.getParent()
得到的是逻辑上的父加载器。
class.getSuperclass()
得到的是继承关系上的父类。
//ClassLoader_Parent_Child 是自己写的类
ClassLoader_Parent_Child.class.getClassLoader(); //sun.misc.Launcher$AppClassLoader@18b4aac2
ClassLoader_Parent_Child.class.getClassLoader().getParent(); //sun.misc.Launcher$ExtClassLoader@60e53b93
ClassLoader_Parent_Child.class.getClassLoader().getParent().getParent(); //null 即:顶层类加载器Bootstrap
ClassLoader_Parent_Child.class.getClassLoader().getClass().getSuperclass(); //class java.net.URLClassLoader
ClassLoader_Parent_Child.class.getClassLoader().getClass().getSuperclass().getSuperclass(); //class java.security.SecureClassLoader
ClassLoader_Parent_Child.class.getClassLoader().getClass().getSuperclass().getSuperclass().getSuperclass(); //class java.lang.ClassLoader
System.out.println(System.getProperty("sun.boot.class.path"));
/*
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/resources.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/rt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/sunrsasign.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jsse.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jce.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/charsets.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jfr.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/classes
*/
System.out.println(System.getProperty("java.ext.dirs"));
/*
/Users/xxx/Library/Java/Extensions
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext
/Library/Java/Extensions
/Network/Library/Java/Extensions
/System/Library/Java/Extensions
/usr/lib/java
*/
System.out.println(System.getProperty("java.class.path"));
/*
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/charsets.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/deploy.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/cldrdata.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/dnsns.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/jaccess.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/jfxrt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/localedata.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/nashorn.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/sunec.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/zipfs.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/javaws.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jce.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jfr.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jfxswt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jsse.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/management-agent.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/plugin.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/resources.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/rt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/ant-javafx.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/dt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/javafx-mx.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/jconsole.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/packager.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/sa-jdi.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/lib/tools.jar
/Users/xxx/IdeaProjects/TestProject/out/production/Module1
/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar
*/