深入理解类加载器

我只知道双亲委派机制还有可以自写个类加载器,其它的一脸懵逼。
我自写的类加载器,以及从应用类加载器调用自写类加载器加载的那个类的main方法代码如下:

package classloadertest;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 父类加载器加载子加载器
 * @author LENOVO
 *
 */
public class MyLoader extends ClassLoader{
	MyLoader(){
		
	}
	MyLoader(ClassLoader parent){//父加载器一个默认构造
		super(parent);
	}
	/**
	 * 重写这个即可,不破坏双亲委派模型
	 */
	@Override
    public Class<?> findClass(String name) {
        FileInputStream in;
        try {
            in = new FileInputStream(
                    new File("E:\\java\\class\\web-inf\\" + name.replace( '.', '\\')+".class"));
        
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int ch = 0;
            while ((ch = in.read()) != -1) {
                out.write(ch);
            }
            byte[] data = out.toByteArray();
            return defineClass(name, data, 0, data.length);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
	
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		MyLoader myLoader=new MyLoader(null);
		try {
			Class<?> c=myLoader.loadClass("test2.Test2");//返回的就是class
			//class.forname
			//A.class
			Object t2=c.newInstance();//因为不能导入另一个classpath下的包,所以定位为obj对象
			System.out.println("test2类加载器:"+t2.getClass().getClassLoader());
			System.out.println("当前运行线程的加载器:"+Thread.currentThread().getContextClassLoader());//当前运行线程的加载器
			for(int i=0;i<t2.getClass().getMethods().length;i++) {
				System.out.println(t2.getClass().getMethods()[i]);
			}
			
//			System.out.println(System.getProperty("java.system.class.loader"));
//			System.out.println("当前程序classLoader名:"+getSystemClassLoader());
//			System.out.println("系统引导程序clsPath:"+System.getProperty("sun.boot.class.path"));
//	        System.out.println("拓展程序clsPath:"+System.getProperty("java.ext.dirs"));
//	        System.out.println("当前java程序的classPath:"+System.getProperty("java.class.path"));
			
			Method[] methods=c.getMethods();//所有的方法,包括父类 基类的方法等等
			for(Method method:methods)
			{
				System.out.println(method.getName());
			}
			methods=c.getDeclaredMethods();//类自身声明的方法
			for(Method method:methods)
			{
				System.out.println("d-"+method.getName());
			}
			//获取具体的方法,执行另一个类加载器的代码
			Method m=c.getMethod("main", String[].class);
			System.out.println(m.getName());
			Object o=m.invoke(null,(Object)new String[] {});//静态方法 不需要传实体; 这不就实现了 父加载器调用子加载器的方法了吗?那什么spi为什么说父调不了子呢
			System.out.println(o);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

目前很穷,需要尽快提升能力,不能花时间研究这个问题,留待日后再深究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值