第十九天 类加载器

 


小知识

BootStarap 是一个JAVA虚拟机器 是存在于JAVA内核中的(也是最高级别的类加载器)

 

System类是由BootStarap类加载器加载的,如果类加载器类为null,则这个类加载器为BootStarap

 

几个类加载器的职责

BootStarap

加载jre/lib/*.jar  例如rt.jar System

ExClassLoader 

加载jre/lib/ext/*.jar

AppClassLoader  

自定义类一般默认都使用该类加载器加载  此类加载器加载classpath指定的所有jar或目录

 

系统的类加载执行顺序

首先会在BootStarap里面查找有没有这个jar包,

如果没有的话会到ExClassLoader 里面查找,

如果还未找到的话才会在APPClassLoader里面查找,找到的话就进行加载 找不到的话就报类无法找到的异常

 

自定义类加载器的执行顺序

首先如果子类覆盖loadclass方法,则不会找找父加载器,如果不覆盖loadclass方法则执行的时候会自动的父类去查找,

如果找不到的话,才回到本类加载器来查找 执行自定义类中重写的方法findClass(String name)在本加载器中查找是否有此类

如果加载的类中又调用另外一个那。那么由当前类加载器来加载那个被调用的类

源代码:

 protected synchronized Class<?> loadClass(String name, boolean resolve)
	throws ClassNotFoundException
    {
	// First, check if the class has already been loaded
	Class c = findLoadedClass(name);
	if (c == null) {
	    try {
		if (parent != null) {
		    c = parent.loadClass(name, false);
		} else {
		    c = findBootstrapClass0(name);
		}
	    } catch (ClassNotFoundException e) {
	        // If still not found, then invoke findClass in order
	        // to find the class.
	        c = findClass(name);
	    }
	}
	if (resolve) {
	    resolveClass(c);
	}
	return c;
    }

 

自定义类加载器

1、自己自定义一个类加载器的时候必须继承自类ClassLoader,并且指定一个父加载器

2、重写findClass(String name)方法

 

指定自义类的类加载器方法

1、自定义类加载器Name.LoadClass();

2、Thread.setContextClassLoader(ClassLoader cl);

 

自定义类加载器的使用示例:

 首先自定义一个要被加载的类:继承自Date并实现toString()方法

public class Demo37_exDate extends Date {
	@Override
	public String toString() {
		System.out.println("Hello,Word");
		
		return null;
	}
}

 

然后自定义一个公共方法:用于对类进行加密

public static void coyher(InputStream is, OutputStream os)
			throws Exception {

		int b = 0;
		while ((b = is.read()) != -1) {
			os.write(b ^ 0xff);
		}
		is.close();
		os.close();

	}


对要被使用的类进行加密处理后,保存到ItcastLib目录下

传入值为  D:\Workspaces\MyEclipse8.5\Test\WebRoot\WEB-INF\classes\Demo37_exDate.class   D:\Workspaces\MyEclipse8.5\Test\ItcastLib\newClass.class 

		FileInputStream fis = new FileInputStream(args[0]);
		FileOutputStream fos = new FileOutputStream(args[1]);
		copyher(fis, fos);


自定义一个类加载器,需要覆盖findClass(String name)方法

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		try {
			name = fileDir +File.separator+ name+".class";
			FileInputStream fis = new FileInputStream(name);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			coyher(fis, baos);
			byte[] b = baos.toByteArray();

			Class c = defineClass(b, 0, b.length);

			return c;
		} catch (Exception e) {
		}

		return null;
	}


使用自定义类加载器加载要已定义的被加载的类:

		Demo37 d = new Demo37("ItcastLib");
		Class c = d.loadClass("newClass");   //如果在包下面的话,必须要加上包名    不使用自定义类加载器还是系统的类加载器,默认根目录为系统目录
		Date date = (Date)c.newInstance();  //被接收方之所以是父类,如果是子类的话,编译器会编译并加载我们加密过的类,会报错
		date.toString();

 

-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值