自定义类加载器的实现,类加载过程

为了安全
每个JAVA程序至少拥有三个类加载器
·引导类加载器 bootstrap
·扩展类加载器 ext
·系统类加载器(应用类加载器)app

引导类加载器负责加载系统类(rt.jar),是虚拟机不可分割的一部分,C实现的,没有对应的classloader对象
例如String.class.getClassLoader()返回null

扩展类加载器用于从jre/lib/ext目录加载标准的扩展,将jar放入该目录,即使没有任何类路径,扩展类加载器也可以找到其中的各个类

系统类加载器用于加载应用类,有CLASSPATH环境变量或-classpath命令选项设置的类路径中的目录里或JAR文件里查找这些类

在oracle的java语言实现中,扩展类加载器和系统类加载器都是java实现的,都是urlclassloader类的实例

类加载器的层次结构,向上依赖加载的顺序,app会要求ext加载,ext要求bootstrap加载
JAVA的类加载是父类委托机制,先找父类加载,不行再找子类加载
这是为了害怕用户自己定义class文件然后自己写一个类加载器来加载原本应该是JVM自己加载的类,会使JVM混乱和影响用户安全。


URL url = new URL("*.jar");
URLClassLoader ucl = new URLClassLoader(new URL[]{url});
Class cl = ucl.loadClass("xxx.class");

因为URLClassLoader构造器中没有指定父类加载器,因此ucl的父亲就是系统类加载器

设置线程的加载器
Thread t .....
t.setContextClassLoader(loader);
在指定类加载器的时候会用到



代码如下:

package classloader;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader {

	private String name;//类加载器的名字
	
	private String path = "/home/chiwei/mydisk/eclipse_workspace/java/src/";//类加载的路径
	
	private final String fileType = ".class";
	
	public MyClassLoader(String name) {
		super();
		this.name = name;
	}
	
	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	private byte[] loadClassData(String name) {
		InputStream in = null;
		byte[] data = null;
		ByteArrayOutputStream baos = null;
		try {
			name = name.replace(".", "\\");
			in = new BufferedInputStream(new FileInputStream(new File(path+name+fileType)));
			baos = new ByteArrayOutputStream();
			int ch = 0;
			while((ch=in.read())!=-1) {
				baos.write(ch);
			}
			data = baos.toByteArray();
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				baos.close();
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return data;
	}
	
	protected Class findClass(String name) {
		byte[] data = this.loadClassData(name);
		return this.defineClass(name, data, 0,data.length);
	}

	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		MyClassLoader loader1 = new MyClassLoader("loader1");
		loader1.setPath("");
		test(loader1);
	}
	
	public static void test(ClassLoader loader) throws Exception{
		Class clazz = loader.loadClass("classloader.MyString");
		Object object = clazz.newInstance();
		MyString ms = (MyString)object;
		System.out.println(ms.toString());
		System.out.println(object==null);
		System.out.println(object.hashCode());
	}

}

package classloader;

public class MyString {

	public java.lang.String toString() {
		return "这是我自定义的String类的toString方法";
	}
	
}
这是我自定义的String类的toString方法
false
926509297




自定义类加载器的实现,类加载过程_第1张图片



























你可能感兴趣的:(Java)