java类加载器-关于保证“一个类的字节码仅被加载一次
? ? ? ?先说一件事,我想在正在情况下(多数情况下)jvm一定希望不希望一个类的字节码被加载多次。那如何保障呢?都知道通过“委托模式”。呵呵,具体的看完下面的内容就知道了。
?
?
?
?
1.ExtClassLoader如何保证字节码仅被加载一次
?
?
? ? ?逻辑上来说ExtClassLoader的父加载器是Bootstrap,。
?
? ? ?具体到代码,ExtClassLoader继承了URLClassLoader,URLClassLoader继承了类SecureClassLoader,最终一直到抽象类ClassLoader。
?
? ? ? 为了保证“一个类的字节码仅被加载一次”这个目标。ExtClassLoader要做的有两件事:
? ? ?a.保证“? private ClassLoader parent;”正确。(对于ExtClassLoader来说这里为null)
? ? ?b.不要重写“?public Class<?> loadClass(*) throws ClassNotFoundException”方法。
?
而最终顶级抽象类ClassLoader中是这么写的
?
protected synchronized Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException {// First, check if the class has already been loadedClass c = findLoadedClass(name);if (c == null) { try {if (parent != null) { c = parent.loadClass(name, false);} else { c = findBootstrapClass0(name);} } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); }}if (resolve) { resolveClass(c);}return c; }??
? ? ? 通过上面的代码可以看出来,实际加载类时,子加载器递归调用父加载器的loadClass(**)方法,直到到达顶级(parent==null)时,方才调用findBootstrapClass0(**)。这时如果抛出了ClassNotFoundException异常,就表示还没加载呢,然后去调用具体的 findClass(name)实现加载。
?
?
?
2.AppClassLoader?如何保证字节码仅被加载一次
?
? ? ? AppClassLoader与ExtClassLoader在保证“一个类的字节码仅被加载一次”这个目标上类似。虽然loadClass方法,但在最后调用了“return super.loadClass(paramString, paramBoolean);”,所以仍旧是OK的。如下所示:
?
?
public synchronized Class loadClass(String paramString, boolean paramBoolean) throws ClassNotFoundException { DownloadManager.getBootClassPathEntryForClass(paramString); int i = paramString.lastIndexOf(46); if (i != -1) { SecurityManager localSecurityManager = System.getSecurityManager(); if (localSecurityManager != null) localSecurityManager.checkPackageAccess(paramString.substring(0, i)); } return super.loadClass(paramString, paramBoolean); }?&
?