今天我遇到的一个面试题为
Thread.currentThread().getContextClassLoader().loadClass(className);//不会调用类的static块代码
class.forName(className);//调用类的static块代码
package cn.hotbain;
import java.io.InputStream;
public class Echo2 {
public static void main(String[] args) throws Exception{
//得到应用类加载器
ClassLoader loader=Thread.currentThread().getContextClassLoader().getParent();
System.out.println(loader);
Thread.currentThread().getContextClassLoader().loadClass("cn.hotbain.Echo");
Thread.currentThread().setContextClassLoader(loader.getParent());
//forName()会造成类的初始化;
//classLoader.loadClass("className");不会造成类的初始化
ClassLoader clazzLoader=Class.forName("cn.hotbain.Echo").getClassLoader();
System.out.println(clazzLoader);
Thread.currentThread().getContextClassLoader().loadClass("cn.hotbain.Echo");
}
private static void test4() throws Exception{
}
private static void test3() throws Exception{
System.out.println("default thread class context loader is "+Thread.currentThread().getContextClassLoader().getClass().getName()
);
ClassLoader classLoader=ClassLoader.getSystemClassLoader().getParent();
Thread.currentThread().setContextClassLoader(classLoader);
System.out.println(Thread.currentThread().getContextClassLoader());
test2();
}
private static void test2() throws Exception{
ClassLoader loader=Echo.class.getClassLoader();
System.out.println(loader);
//如果是用类加载器加载resources的话,那么就会从指定的Loader的指定位置加载(例如:extLoader从ext加载resource)
InputStream ins=loader.getResourceAsStream(".classpath");
ins.close();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("当前线程启动的classLoader为"+Thread.currentThread().getContextClassLoader());
}
}).start();
}
private static void test1() throws Exception{
//如果文件路径是以/开头时,那么就会从绝对路径下读取文件。否则就会以相对路径的方式查找
InputStream ins =Echo2.class.getResourceAsStream("/note.txt");
System.out.println(ins);
ins.close();
}
}
在tomcat中每一个app都会对应一个加载器Loader1,但是其父加载器去都是同一个StandardClassLoader,当需要从tomcat的lib下分享共同的资源的时,需要将其放入到指定lib下。当需要在web-inf下访问资源时,需要将资源放到web-inf下