黑马程序员-----类加载器与委托机制总结*

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

 

 类加载器:

类加载器,
   作用:类加载器负责加载java类的字节码文件到java虚拟机中
   过程:首先java源程序在经过编译器编译之后形成class文件,类加载器负责负责读取class文件,
              并转换成java.lang.Class类的一个实例,每个这样的实例都表示一个java类

  1、类加载器的作用:当JVM运作时需要使用某个类,就需要加对应的字节码文件加载到内存中,而类加载器就是负责这个工作的。如果需要多次使用该字节码文件,类加载器不会多次加载,而是直接使用内存中的字节码
  2、系统默认三个类加载器:BootStrap、ExtClassLoader、AppClassLoader,类加载器也是类.
        但是BootStrap特殊,它不是类,它是嵌套在JVM中的,java程序调用它会返回null
        BootStrap类加载随着JVM的启动而启动,它的作用是加载其他的系统默认类加载器(ExtClassLoaderAppClassLoader)
     
  3、如果发生了空指针异常,那么一定是某方法前的某对象为null
 
  4、类加载器的管辖范围:
    BootStrap----------------jre/lin/re.jra
    ExtClassLoader-----------jre/lin/ext/*.jar
    AppClassLoader-----------CLASSPATH指定的所有jar或目录

 

public class ClassLoaderTest {
	public static void main(String[] args) {
		/*获取类加载器的名称*/
		//第一步:获取class类对象
		Class c = ClassLoaderTest.class;
		//第二步:获取该类类加载器对象(也就是获取到加载该类的类加载器)
		ClassLoader cl = c.getClassLoader();
		//第三步:获取该类加载器的Class对象
		Class c2 = cl.getClass();
		//第四步:返回该类对象表示的实体名称
		String str = c2.getName();
		System.out.println(str);    //结果是AppClassLoader类加载器
		
		
		/*获取null类加载器,也就是BootStrap,System类就是由此类加载器加载的*/
		//第一步:获取class类对象
		Class c3 = System.class;
		//第二步:获取该类类加载器(也就是获取到加载该类的类加载器)
		ClassLoader cl1 = c3.getClassLoader();
		System.out.println(cl1);


 


    


委托机制:

1、当需要某个类加载器去加载指定的类时,由某个子类加载器层层向上推进到BootStrap加载器,如果BootStrap加载器无法加载,又会层层向下递推到子类加载器,如果退回到发起的类加载器还是没有办法加载的话,那么就会抛出ClassNotFoundException异常

2、好处:如果两个自定义类加载器,如果没有委托机制,他们去加载同一个类时就会在内存中产生两份相同的字节码文件,这样浪费资源,而如果有了委托机制,加载类时都会去父类加载器中查看是否能够加载,再次加载同一个类时,会直接使用内存中已经加载过的,这样节省了资源

测试委托机制:

 

/*测试类加载器的委托机制
		 * 1、注意到AppClassLoader和ExtClassLoader打印出的类名是Launcher,这说明他们都是Launcher类的内部类
		 * */
		//第一步:获取类加载器对象
		ClassLoader clo = ClassLoaderTest.class.getClassLoader();
		//第二步:返回该类加载器的委托的父类加载器
		while(clo!=null){
			System.out.println(clo.getClass().getName());
			//返回委托的父类加载器
			clo = clo.getParent();
		}
		System.out.println(clo);
	}

 

有一道面试题:能否自己创建java.lang.System类?

答:不能,因为即使自己创建了System类,因为加载时受委托机制的影响,父类BootStrap会加载java系统中的System,而不会加载自定义的System类

怎么解决呢?

答:可以自定义类加载器

 

 

 

自定义类加载器:

loadClass方法会自动调用findClass方法!

两种方式:

一,覆盖ClassLoader抽象父类中的loadClass方法, 但是这样自己要重新编写双亲委托机制,这样很麻烦

二,不用覆盖loadClass方法,而是覆盖findClass方法,这样的话当loadClass方法中调用父类加载器加载失败,就会调用到自定义的findClass方法,这样既能保证自定义的类加载器符合双亲委托机制

 

 



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

详细请查看:http://edu.csdn.net
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值