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 loaded
	Class 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);
    }
 

&

 

你可能感兴趣的:(jvm)