虾屮蛋

导航

 

    用自定义类加载器加载类,每次用一个classloader实例来加载,每次加载的class都是最新的,可以实现类的热加载,但类的静态变量也每次都是初始值,如下例子:

// 自定义classloader, 来自《深入理解java虚拟机》一书
class MyClassLoader extends ClassLoader {
	@Override
	public Class<?> loadClass(String name) throws ClassNotFoundException {
		try {
			String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
			InputStream is = getClass().getResourceAsStream(fileName);
			if(is == null) {
				return super.loadClass(name);
			}
			byte[] b = new byte[is.available()];
			is.read(b);
			return defineClass(name, b, 0, b.length);
			
		} catch (Exception e) {
			throw new ClassNotFoundException();
		}
	}
}

// 加载Test类
public class ClassLoadTest {
	public static void main(String []args) throws Exception {
		while(true) {
			Object obj = new    MyClassLoader().loadClass("com.java.load.Test").newInstance();	
			System.out.println(obj.getClass().getClassLoader());
			LoadInterface c = (LoadInterface)obj; 	
			c.method1();
			Thread.sleep(10000);
		}
	} 

// 调用上下文classloader,加载类并返回
    public Object getObject(String className) throws Exception, IllegalAccessException, ClassNotFoundException {
         System.out.println("test1: " + ClassLoadTest.class.getClassLoader());
        System.out.println("test2: " + Thread.currentThread().getContextClassLoader());
         Object obj = Thread.currentThread().getContextClassLoader().loadClass(className).newInstance();
         return obj;
    } } public class Test { private static int a = 1; public void method1() { System.out.println("this is method1 in test11"); System.out.println(a++); }

    public static void main(String []args) throws Exception, ClassNotFoundException, Exception {
        while(true) {
            Object obj = new ClassLoadTest().getObject("com.java.load.Test");
            Test t = (Test)obj;
            t.method1();  
            Thread.sleep(10000);
        }
    } }

     上例中,执行ClassLoadTest,每次MyClassLoader实例对象都不一样,打印出来的值a一直是1,如果修改Test类中method1方法,打印信息也会改变。

      将ClassLoadTest.class放在JRE的ext/classes下,让ext classloader去加载,执行Test类方法时,ClassLoadTest的classloader一直是ExtClassLoader的同一个实例对象,Test的classloader一直是AppClassLoader的同一个实例对象。Test被同一个classloader加载。

   

 

posted on 2013-04-13 08:48  虾屮蛋  阅读(167)  评论(0)    收藏  举报