黑马程序员
----------------------
类加载器及其委托机制的深入分析:
类加载器的委托机制:
当java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
1、首先当线程的类加载器去加载线程中的第一个类。
2、如果类A中引用的类B,java虚拟机将使用加载类A的类装载器来加载类B。
3、还可以直接调用ClassLoader.loadClass()方法来指定某个加载器去加载某个类。
每个类加载器加载类时,又先委托给其上级类加载器。
当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛出ClassNotFoundException,不是再取找发起者类加载器的儿子,因为没有getChild方法,即使有,那有多少儿子,找哪个呢?
自定义类加载器的编写原理分析:
写自己的类加载器,字节的类加载器覆盖findClass(),就可以获取到对应的字节码,将这些字节码交给definClass()方法将其变成Class对象。
模板方法设计模式
父类-->loadClass/findClass()/得到Class文件转换成字节码-->definClass()把自己数组变成Class
子类1(自己干)
子类2(自己干)
总体流程在父类规定好,子类继承父类方法,父类定义局部细节为抽象方法,子类填写对应抽象方法,流程在父类中已经规定好。
自定义类加载器:
package com.classloader;
/**
* 一、ClassLoader加载类的顺序
* 1.调用 findLoadedClass(String) 来检查是否已经加载类。
* 2.在父类加载器上调用 loadClass 方法。如果父类加载器为 null,则使用虚拟机的内置类加载器。
* 3.调用 findClass(String) 方法查找类。
* 二、实现自己的类加载器
* 1.获取类的class文件的字节数组
* 2.将字节数组转换为Class类的实例
* @author Administrator
*
*/
public class ClassLoaderTest {
public static void main(String[] args)throws InstantiationException, IllegalAccessException, ClassNotFoundException {
MyClassLoader cl = new MyClassLoader("myClassLoader");
Class<?> clazz = cl.loadClass("com.classloader.Animal");
Animal animal=(Animal) clazz.newInstance();
animal.say();
}
}
package com.classloader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
public class MyClassLoader extends ClassLoader {
// 类加载器的名称
private String name;
// 类存放路径
private String path = "G:\\MyWorkspaces\\Test\\src";
MyClassLoader(String name) {
this.name = name;
}
MyClassLoader(ClassLoader parent, String name) {
super(parent);
this.name = name;
}
// 重写findClass方法
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] data = loadClassData(name);
return this.defineClass(name, data, 0, data.length);
}
public byte[] loadClassData(String name) {
try {
name = name.replace(".", "//");
FileInputStream is = new FileInputStream(new File(path + name
+ ".class"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b = 0;
while ((b = is.read()) != -1) {
baos.write(b);
}
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.classloader;
public class Animal {
public void say(){
System.out.println("hello world!");
}
}
----------------------android培训、java培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net/heima