JVM---类加载器

先来看下classloader的加载代码:public abstract class ClassLoader

 

     //注:如果想改变加载顺序,可将该方法覆盖,像webappclassloader
    protected synchronized Class<?> loadClass(String name, boolean resolve)   
	    throws ClassNotFoundException   
	    {   	    //检查是是否已经加载过   
	    Class c = findLoadedClass(name);   
	    if (c == null) {   
	        try {   
	        if (parent != null) {   
	            //代理给parent去加载类   
	            c = parent.loadClass(name, false);   
	        } else {   
	            //由Bootstrap去加载类   
	            c = findBootstrapClass0(name);   
	        }   
	        } catch (ClassNotFoundException e) {   
	            //parent和Bootstrap都无法加载,则由自定义的方式去加载类   
	            //通过扩展该方法来实现自定义的类加载器   
	            c = findClass(name);   
	        }   
        }  
    protected Class<?> findClass(String name) throws ClassNotFoundException { 
	     throw new ClassNotFoundException(name);//具体加载交给子类实现
    }

 

 

ExtClassLoader与AppClassLoader都是 java.net.URLClassLoader的子类别,您可以在使用java启动程式时,使用以下的指令来指定ExtClassLoader的搜寻路径:
java -Djava.ext.dirs=c:/workspace/ YourClass
可以在使用java启动程式时,使用-classpath或-cp来指定AppClassLoader的搜寻路径,也就是设定Classpath:
java -classpath c:/workspace/ YourClass
ExtClassLoader与AppClassLoader在程式启动后会在虚拟机器中存在一份,您在程式运行过程中就无法再改变它的搜寻路径,如果在程式运行过程中,打算动态决定从其它的路径载入类别,就要产生新的类别载入器。
您可以使用URLClassLoader来产生新的类别载入器,它需要java.net.URL作为其参数来指定类别载入的搜寻路径,例如:
URL url1 = new URL("file:/d:/workspace/");
URLClassLoader urlClassLoader1 =  new URLClassLoader(new URL[] {url1});
Class c1 = urlClassLoader1.loadClass("ClassDemoTest");
在新增了ClassLoader后,您可以使用它的loadClass()方法来指定要载入的类别名称,新增 ClassLoader时,会自动将新增的ClassLoader的parent设定为AppClassLoader,并在每次载入类别时,先委托 parent代为搜寻,所以上例中搜寻ClassDemoTest类别时,会一路往上委托至Bootstrap Loader先开始搜寻,接着是ExtClassLoader、AppClassLoader,如果都找不到,才使用新增的ClassLoader搜寻。
由同一个ClassLoader载入的类别档案,会只有一份Class实例,如果同一个类别档案是由两个不同的ClassLoader载入,则会有两份不同的Class实例,注意这个说法,如果有两个不同的ClassLoader搜寻同一个类别,如果在parent的 AppClassLoader搜寻路径中就可以找到,则Class实例就只会有一个,如果是由各自的ClassLoader搜寻到,则Class的实例会有两份。

你可能感兴趣的:(类加载器)