1,什么是双亲委派机制?
我的理解是,在java中,当类加载器需要对class文件进行加载时,会递归调用父加载器,当父加载器加载失败时,再向下递归传递进行加载,最后加载成功或失败。(感觉有点绕~)
2,类加载器有哪些?
3,执行流程是怎样的?
4,优点
1,安全加载:当加载类时,先委托父加载器加载可以避免破坏我们核心包里面的类。如我们可以项目里面建一个java.lang.String的类,但这样运行时实际找到的是Bootstrap ClassLoad加载的核心包里面的String,从而起到保护作用。
2,避免类重复加载:当父加载器已经加载了某类时,子加载器就没必要再加载一次。
5,打破双亲委派
创建一个类继承ClassLoader,重写loadClass()方法。
但重写的时候需要注意,核心类文件还是需要向上传递进行加载(loadClass),只有需要自定义加载器加载的目录才直接加载(findClass);否则会出现Object类找不到异常
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) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
//*********** 判断如果为当前需要当前加载器直接加载的目录,则不再向上传递
if(name.startsWith("com.test")){
c = findClass(name);
}else{
//否则按照向上加载,避免出现Object类未找到异常
c = this.getParent().loadClass(name);
}
//*************
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
MyClassLoader myClassLoader = new MyClassLoader("D:/test");
Class clazz = myClassLoader.loadClass("com.test.User");
Object obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("study");
method.invoke(obj,null);
System.out.println(clazz.getClassLoader().getClass().getName());
}