java高新学习笔记3

黑马程序员

       ----------------------android培训java培训 、期待与您交流! ----------------------

类加载器及其委托机制的深入分析:

1、java虚拟机中可以安装多个类加载,系统默认三个主要的类加载器,每个类负责加载特定位置的类:BootStrap、ExtClassLoader、AppClassLoader。

2、类加载器也是java类、因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载不是java类、这正是BootStrap.

3、java虚拟机中的所有类加载器采用具有父子关系的树形结构化进行组织、在实例化每个类加载器对象时,需要为其制定一个父级类装载器对象或者默认采用系统类转载器为其父类级加载。

 

 

 

类加载器的委托机制:
当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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值