黑马程序员-类加载器

来源:互联网 发布:mac os x10.12镜像下载 编辑:程序博客网 时间:2024/04/30 06:32
------- 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 stubClassLoader 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;@Overrideprotected 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";}}



原创粉丝点击