Java双亲委派机制
先了解一下几个类:
/* 私有构造器,只有JVM可以生成Class对象,这个构造方法不使用,并是为了防止默认的构造方法会生成(没有构造方法的时候,会有一个空餐的构造方法)
* Private constructor. Only the Java Virtual Machine creates Class objects.
* This constructor is not used and prevents the default constructor being generated.
*/
private Class(ClassLoader loader) {
// Initialize final field for classLoader. The initialization value of non-null
// prevents future JIT optimizations from assuming this final field is null.
classLoader = loader;
}
/**
* Returns the class loader for the class. Some implementations may use
* null to represent the bootstrap class loader. This method will return
* null in such implementations if this class was loaded by the bootstrap
* class loader.返回这个类的类加载器,某些执行过程中可能使用Null来代替bootstrap
* 为null的话,就直接返回null,否则会往下走,一直涉及权限相关的东西(这个过程会修改ClassLoader,
* 所以不是它不为null的时候立即就返回ClassLoader)
*/
2.ClassLoader:将一些实体类,接口等转化为虚拟机中存储的对象(Class),完成这个任务的角色就是ClassLoader,翻译过来就是类加载器,ClassLoader在java中也有对应的抽象类,我们平时所说的三个类加载器的UML图如下(BootStrap是源代码中提了一下,并没有对应的Java类,是Cpp/C写的) 
需要注意的是,平时有些博客在写到双亲委派机制的时候,总是说父类加载器,其实他们想说的是是加载器中的属性parent,很多一知半解的小伙伴就会以为是他的父类,以为是"父类"加载器
// "父”类加载器代理声明:VMXXX,因此,所有的新属性都必须在它之后添加
private final ClassLoader parent;
// binary name:例如"java.lang.String" "javax.swing.JSpinner$DefaultEditor"
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 查看该类是否已经被加载了,底层调用了native方法findLoadClass0(name),就是参数中的name
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
}
if (c == null) {
// 还是为null的话,会调用自己的findClass()方法,这就是由上往下加载的关键
long t1 = System.nanoTime();
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
protected Class<?> findClass(final String name)
throws ClassNotFoundException
{
final Class<?> result;
try {
result = AccessController.doPrivileged(
new PrivilegedExceptionAction<Class<?>>() {
public Class<?> run() throws ClassNotFoundException {
String path = name.replace('.', '/').concat(".class");
//这个就是非BootStrap能够加载此类的关键
Resource res = ucp.getResource(path, false);
if (res != null) {
try {
return defineClass(name, res);
} catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
} else {
return null;
}
}
}, acc);
} catch (java.security.PrivilegedActionException pae) {
throw (ClassNotFoundException) pae.getException();
}
if (result == null) {
throw new ClassNotFoundException(name);
}
return result;
}
//查看各个类加载器的Parent属性是什么