黑马程序员_Java基础加强4

---------------------- Android、Java开发期待与您交流! ----------------------

     类加载器

         类加载器负责加载类的对象,它可以在将类加载到虚拟机中的时候坚持类的完整性。

         每个程序至少拥有三个类加载器:

1.引导类加载器

2.扩展类加载器

3.系统类加载器(也称应用类加载器)

        引导类加载器负责加载系统类(通常从JAR文件rt.jar中进行加载)。它是虚拟机整体中的一部分,通常用C语言来实现。引导类加载器没有对应的ClassLoader对象,如,String.class.getClassLoader()将返回null。

       扩展类加载器用于从jre/lib/ext目录加载“标准的扩展”。可以将JAR文件放入目录,这样即使没有任何类路径,扩展类加载器也可以找到其中的各个类。

       系统类加载器用加载应用类。它由CLASSPATH环境变量或者-classpath命令行选项设置的类路径中的目录里或者JAR/ZIP文件里查找这些类

      在Sun公司的Java语言实现中,扩展类加载器和系统类加载器都是Java来实现的。它们都是URLClassLoader类的实例

警告:如果JAR文件放入jre/lib/ext目录中,并且在它的类中有一个类需要调用系统类或者扩展类,那么就会遇到麻烦。扩展类加载器并不使用类路径。在使用扩展目录来解决类文件的冲突之前,要牢记这种情况

注意:除了所有已经提到的位置,还可以从jre/lib/endorsed目录中加载。这种机制只能用于将某个标准的Java类库替换为更新的版本(例如那些支持XML和CORBA的类)

类加载器的层次结构

        类加载器有一种父/子关系。除了引导类加载器外,每个类加载器都有一个父类加载器。根据规定,类加载器会为它的父类加载器提供一个机会,以便加载任何给定的类,并且只有在其父类加载器加载失败时,它才会加载该给定类。例如,当要求系统类加载器加载一个系统类(比如,java.util.ArrayList)时,它首先要求扩展类加载器进行加载,扩展类加载器则首先要求引导类加载器进行加载。引导类加载器查找并加载rt.jar中的这个类,而无须其他类加载器做更多的搜索

自定义类加载器

       需要继承ClassLoader类并重写父类findClass(String className)方法。

      ClassLoader超类的loadClass方法用于将该类的加载操作委托给其父类加载器去进行,只有当该类尚未加载并且父类加载器也无法加载该类时,才调用findClass方法

      如果要实现该方法,要做到以下几点:

1.为来自本地文件系统或者其它来源的类加载其字节码

2.调用ClassLoader超类的defineClass方法,向虚拟机提供字节码


常用方法:

java.lang.Class

         ClassLoader  getClassLoader():返回该类的类加载器,如果父类是引导类加载器则返回null

java.lang.ClassLoader

         protected Class defineClass(String name,byte[] b,int off,int len):将一个 byte 数组转换为 Class 类的实例。

         protected Class findClass(String name):使用指定的二进制名称查找类

         InputStream getResourceAsStream(String filePath):返回读取指定资源的输入流。

        static  ClassLoader  getSystemClassLoader():返回委托的系统类加载器。

import java.util.Date;

public class ClassLoaderAttachment extends Date {

	private static final long serialVersionUID = 1L;

	public String toString() {
		return "hello itcast!";
	}
}

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
 * 自定义类加载器类
 * @author wxd
 *
 */
public class MyClassLoader extends ClassLoader {

	private String classDir;

	public MyClassLoader() {
	}

	public MyClassLoader(String classDir) {
		this.classDir = classDir;
	}

	public static void cypher(InputStream ips, OutputStream ops)
			throws IOException {
		int b = -1;
		while ((b = ips.read()) != -1) {
			ops.write(b);
		}
		ips.close();
		ops.close();
	}

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		String classFileName = classDir + "\\" + name+".class";
		try {
			FileInputStream fis = new FileInputStream(classFileName);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			cypher(fis, bos);
			fis.close();
			byte[] bytes = bos.toByteArray();
			return defineClass(bytes, 0, bytes.length);
		} catch (Exception e) {
		}
		System.out.println("classFileName:" + classFileName);
		return super.findClass(classFileName);
	}

}

import java.util.Date;

public class ClassLoaderTest {
	@SuppressWarnings("rawtypes")
	public static void main(String[] args) throws Exception {
		System.out.println(ClassLoaderTest.class.getClassLoader().getClass()
				.getName());
		System.out.println(System.class.getClassLoader());
		ClassLoader loader = ClassLoaderTest.class.getClassLoader();
		while (loader != null) {
			System.out.println(loader.getClass().getName());
			loader = loader.getParent();
		}
		System.out.println("loader:" + loader);
		Class clazz =new MyClassLoader("itcastlib").loadClass("ClassLoaderAttachment");		
		Date date = (Date) clazz.newInstance();
		System.out.println("date:"+date);
	
	}

}


---------------------- Android、Java开发期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值