黑马程序员 java学习笔记——类加载器

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------

概述

概念:类加载器是加载类的工具。
作用:将是类的字节码文件加载进内存。

简要介绍

1、Java虚拟机中可以安装多个类加载器,默认有三个类加载器:BootStrap、ExtClassLoader、AppClassLoader,每一个类负责加载特定位置的类。
2、类加载器其实其本身也是类,也需要被加载。所以,必须有第一个类加载器不是类,这个就是BootStrap。
3、java虚拟机中的所有类加载器采用具有父子关系的树形结构进行组织,在实例化每个类加载器对象时,需要为其制定一个父级类加载器对象或者默认采用系统类装载器为其父级类加载器。

类加载器的委托机制

1、当java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
① 首先当前线程的类加载器去加载线程中的第一个类。
② 如果类A中引用了类B,java虚拟机将使用加载类A的类加载器来加载类B。
③还可以直接调用ClassLoader的loadClass方法来指定某个类加载器去加载某个类。
2、每个类加载器加载类时,又先委托给其上级类加载器
①每个类加载器本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类加载器去加载类,这就是类加载器的委托模式。类加载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级退到子孙类加载器去进行真正的加载。
②当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不到,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild方法,即使有,那么多儿子,到底找哪一个?
③有一道面试题,能不能自己写个类叫java.lang.System,为了不让我们写我们System,类加载器采用委托机制,这样可以保证爸爸们优先,也就是总是使用爸爸们能找到的类,这样总是使用java系统提供的System。

类加载器之间的父子关系及管辖范围图

黑马程序员 java学习笔记——类加载器_第1张图片

示例代码

public class Demo{
	public static void main(String[] args){
		String str=Demo.class.getClassLoader().getClass().getName();
		sop(str);
		ClassLoader cl =System.class.getClassLoader();
		sop(cl);

		ClassLoader loader=Demo.class.getClassLoader();
		while(loader!=null){
			sop(loader);
			loader=loader.getParent();
		}
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
}
//null
//sun.misc.Launcher$AppClassLoader@197d257
//sun.misc.Launcher$ExtClassLoader@7259da

自定义的类加载器

简易示例代码如下:
import java.io.*;
class MyClassLoader extends ClassLoader{//定义一个类继承ClassLoader类
		private String classdir;
		public MyClassLoader(String classdir){
			this.classdir=classdir;
		}
		//加密算法
		public void cypher(InputStream is,OutputStream os)throws IOException{
			int len=0;
			while((len=is.read())!=-1){
				os.write(len^0xff);
			}
			is.close();
			os.close();
		}
	   //覆盖ClassLoader类中的findClass方法.
	   @Override
	   protected Class findClass(String name)throws ClassNotFoundException {
		   try {
			   FileInputStream fis=new FileInputStream(name);
			   ByteArrayOutputStream bos=new ByteArrayOutputStream();
			   fis.close();
			   int len=0;
			   cypher(fis,bos);
			   byte[] data=bos.toByteArray();
			   Class clazz=defineClass(data,0,data.length);
			   return clazz;
		   }catch(FileNotFoundException e) {
			   //TODO Auto-generated catch block
			   e.printStackTrace();
		   }catch(IOException e) {
			   //TODO Auto-generated catch block
			   e.printStackTrace();
		   }
		   return super.findClass(name);
	   }
}

----------------------  ASP.Net+Android+IO开发S .Net培训 、期待与您交流! ----------------------

你可能感兴趣的:(java基础)