黑马程序员-类加载器

------- android培训java培训、期待与您交流! ----------
类加载器:
java虚拟机可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:
BootStrap,ExtClassLoader,AppClassLoader。
类加载器也是java类,也要被类加载器加载,它就是BootStrap,它不是一个java类,而是通过C++
写在jvm里的。
类加载器对应的加载类区别:
//BootStrap---->JRE/lib/rt.jar
//ExtClassLoader--->JRE/lib/ext/*.jar
//AppClassLoader---->Classpath指定的所有jar或目录


类加载器的委托机制:
当java虚拟机要加载一个类时:
1,首先当前线程的类加载器去加载线程中的第一个类
2, 如果类A引用类B,java虚拟机使用加载类A的类加载器来加载类B。
3,还可以直接调用ClassLoader的loadClass()方法来指定某个类加载器去加载某个类。
每个类加载器加载类时,先委托给其上级类加载器,直到BootStrap,再从BootStrap开始加载,如果没有加载到类,返回下一极类加载器加载,直到发起者类加载器。
当所有祖宗类加载器没有加载到类,回到发起者加载器,还加载不了,则抛出ClassNotFoundException

能不能写个类叫 java.lang.System?
通常不能写,因为类加载器加载System类时,因为委托机制,所以BootStrap会直接先加载rt.jar
中的System类,Classpath下的System类永远加载不到。
如果需要加载写的这个System类,可以自定义一个类加载器,指定加载这个System类。

获取一个类的类加载器及其所有父类加载器
public class ClassLoaderTest {


	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ClassLoader clazzLoader = ClassLoaderTest.class.getClassLoader();
		System.out.println(clazzLoader.getClass().getName());
		while(clazzLoader.getParent()!=null){
			clazzLoader = clazzLoader.getParent();
			System.out.println(clazzLoader.getClass().getName());
		}
		System.out.println(clazzLoader.getParent());
	}
}

自定义解密类加载器加载加密的class文件:
解密类加载器测试类:ClassLoaderTest:
package cn.it.cast;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;


public class ClassLoaderTest extends ClassLoader{


	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		/*ClassLoader clazzLoader = ClassLoaderTest.class.getClassLoader();
		System.out.println(clazzLoader.getClass().getName());
		while(clazzLoader.getParent()!=null){
			clazzLoader = clazzLoader.getParent();
			System.out.println(clazzLoader.getClass().getName());
		}
		System.out.println(clazzLoader.getParent());*/
		
		//System.out.println(new ClassAttatchment().toString());
		
		Class clazz = new MyClassLoader("itcastlib").loadClass("cn.it.cast.ClassAttatchment");
		Date d = (Date)clazz.newInstance();
		System.out.println(d);
	}	
}


自定义解密类加载器类MyClassLoader:
package cn.it.cast;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;


public class MyClassLoader extends ClassLoader{


	public static void main(String[] args) throws Exception{
		String srcPath = args[0];
		String destDir = args[1];
		String fileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);
		String destPath = destDir+"\\"+fileName;
		
		FileInputStream fis = new FileInputStream(srcPath);
		FileOutputStream fos = new FileOutputStream(destPath);
		cypher(fis,fos);
		fis.close();
		fos.close();
	}
	
	private static void cypher(InputStream ips,OutputStream ops)throws Exception{
		int b = 0;
		while((b=ips.read())!=-1){
			ops.write(b ^ 0xff);
		}
	}
	private String classDir;
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		String classFileName = classDir + "\\" + name.substring(name.lastIndexOf('.')+1) + ".class";
		try {
			FileInputStream fis = new FileInputStream(classFileName);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			cypher(fis,bos);
			fis.close();
			System.out.println("aaa");
			byte[] bytes = bos.toByteArray();
			return defineClass(null,bytes, 0, bytes.length);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return super.findClass(name);
	}
	public MyClassLoader(){
		
	}
	public MyClassLoader(String classDir){
		this.classDir = classDir;
	}
}

要加密的类:ClassAttatchment:
package cn.it.cast;


import java.util.Date;


public class ClassAttatchment extends Date{
	public String toString()
	{
		return "hello,itcast";
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值