关于ClassLoader的一个小实验

package t;

import java.net.URL;

public class Test2 {

	public static void main(String[] args) throws Exception {

		ClassLoader loader1 = ClassLoader.getSystemClassLoader();
		ClassLoader loader2 = Thread.currentThread().getContextClassLoader();
		ClassLoader loader3 = Test2.class.getClassLoader();
		System.out.println("loader1==loader2	"+(loader1==loader2));
		System.out.println("loader1==loader3	"+(loader1==loader3));
		
		//为当前线程指定ClassLoader
		Thread.currentThread().setContextClassLoader(new ClassLoader(){});
		loader2 = Thread.currentThread().getContextClassLoader();
		System.out.println("loader1==loader2	"+(loader1==loader2));
		
		URL url = loader1.getResource("");
		System.out.println("url="+url);
		System.out.println("url.getPath()="+url.getPath());
	}
}

输出:

loader1==loader2	true
loader1==loader3	true
loader1==loader2	false
url=file:/D:/workspace1/TestOrac/bin/
url.getPath()=/D:/workspace1/TestOrac/bin/

 一些说明:

ClassLoader java.lang.ClassLoader.getSystemClassLoader()
返回委托的系统类加载器。该加载器是新的 ClassLoader 实例的默认委托父类加载器,通常是用来启动应用程序的类加载器。

ClassLoader java.lang.Thread.getContextClassLoader()
返回该线程的上下文 ClassLoader。上下文 ClassLoader 由线程创建者提供(Thread提供了setContextClassLoader(ClassLoader cl)方法用于为该线程指定ClassLoader),供运行于该线程中的代码在加载类和资源时使用。如果未设定,则默认为父线程的 ClassLoader 上下文。原始线程的上下文 ClassLoader 通常设定为用于加载应用程序的类加载器。

ClassLoader java.lang.Class.getClassLoader()
返回该类的类加载器。有些实现可能使用 null 来表示引导类加载器。如果该类由引导类加载器加载,则此方法在这类实现中将返回 null。

关于Classloader.getResource()

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

public class Test {

	public static void main(String[] args) throws UnsupportedEncodingException {

		String url =Thread.currentThread().getContextClassLoader().getResource("").getPath();
		
		System.out.println("before:"+url);
		
		System.out.println("after:"+URLDecoder.decode(url, "utf-8"));
		
//		before:/C:/Program%20Files/%e6%96%b0%e5%bb%ba%e6%96%87%e4%bb%b6%e5%a4%b9/
//		after:/C:/Program Files/新建文件夹/
	}
}

猜你喜欢

转载自huangqiqing123.iteye.com/blog/1461359