第十九天 类加载器

来源:互联网 发布:linux终端删除~$ 编辑:程序博客网 时间:2024/05/01 22:09

 


小知识

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 loadedClass 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 {@Overridepublic 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)方法

@Overrideprotected 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();

 

-

原创粉丝点击