也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。  
本文基于最新得JDK5,然后将将诉的内容都包含了最基本的原理,希望你能更加深入了解自己所使用得语言。 
  
  
 理解CLassLoader 
  
如果你自己定义叻一个 org.test.Object 。 
你在程序中这样写: 
import ort.test.Object 
Object o = new String();  也许你欣然以为这样写没问题,但实际上你错了。   
一个Class在JVM中得标识呢是由它得 PackAge 和 类名决定得。 也就是它得名称空间。 
 org.test.Object 可不是  java.lang.Object  
  
在java中呢,每个类都是java.lang.Class得实例。也就是说。 
java.lang.Class klass = Myclass.class;
 Myclass myclass  = new Myclass() 等同于  myclass.newInstance();
  
  
  
在JVM中。所有得类都由  java.lang.ClassLoader.(或者是它得子类开发者自己添加得),我们在启动得时候都是借力于JAVA_HOME/jre/rt.jar。  不过我们发现JDK这里并没有任何文档介绍bootstrap.jar。 实际上bootstrap Class Loader是JDK之外得,它得方式和JVM的是不一样的。(本文不做介绍)  
java.net.URLClassLoader 
java.security.SecureClassLoader 
java.rmi.server.RMIClassLoader 
sun.applet.AppletClassLoader  
Class Loaders工作原理 
   
  除了bootstrap之外,所有的Classloader都有个父类Class Loader ,他们都是instanceof java.lang.ClassLoader  
  
来看看JDK1.5中的工作原理。 
假如有个方法loadClass 
  
protected synchronized Class<?> loadClass     (String name, boolean resolve)     throws ClassNotFoundException{
      // First check if the class is already 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 to find the class.             c = findClass(name);         }     }     if (resolve) {     resolveClass(c);     }     return c; } 
   
那么Set它父类的方式有两种。 
public class MyClassLoader extends ClassLoader{     public MyClassLoader(){         super(MyClassLoader.class.getClassLoader());     } } 
或者 
public class MyClassLoader extends ClassLoader{     public MyClassLoader(){         super(getClass().getClassLoader());     } } 
  
这里是首选第一种。  
因为getClass()是在构造函数内部得方法,所以必须要有构造函数代码存在,但是如果不存在,那就找父类得classloader 一直找啊找,直至找到到findBootstrapClass, 如果它也不存在得话,那时候findClass()方法会被调用执行。。到那时候会报一个ClassNotFoundException。  
  
来看看findClass()得代码 
     protected Class<?> findClass(String name)         throws ClassNotFoundException {         throw new ClassNotFoundException(name);     } 
  
在findClass() 方法内 class loader要取得到得字节码(就是.class文件里得内容),然而不不一定就是.class文件, 这些字节码可以来自本地,也可以是系统,网络(借着这个你可以理解一下Cobra,RMI),也可以是用 BCEL(Apache一个基于字节码得一个引擎库) ...等等。 一但字节码找到了。那时候就开始执行defineClass()方法。那时候会定义出一个类的实例来。   如果有两个ClassLoader 实例化两个相同得代码,defineClass()定义得两个类也是不同得。详细请看(Java language specification) 
  
  
  
  
下图展示了一个MyMainclass.class如何装载执行。(由多个classLoader加载同一个Target.class),----和我们想象中有差别得是,它首先是由于BootStarpClassLoader载入得。 
根据上面得解析,既然两个classLoader()载入Target.class得字节码 ,那defineClass()就会产品两个class得定义得。 
  
所以很容易得出结论Target target3 = (Target) target2; 是不能被执行地。
  
  
  
  
  
 
 
  |