Java类加载器的机制

        运行一个java程序启动一个JVM,不论该java程序多么复杂,有多少线程都数据JVM这个进程内。不同的JVM之间不会共享数据。

 

        系统可能在第一次使用类时加载该类,也可能预加载类,JVM提供类加载器。类加载器负责将.class文件加载到内存中并为之生成对应的java.lang.class对象,同一个类不会JVM被重复载入。JVM是通过类的全限定类名(即包名和类名)作为唯一标识判断一个类是否被加载过。

 

        JVM启动时会形成三个类加载器组成初始类加载器层次结构,结构如下:

 

Bootstrap:

         根类加载器,负责加载Java的核心类,它不是java.lang.ClassLoader的子类,是由JVM自身实现的。可以从网上找一些程序代码把这些核心类的jar包输出。

         Java的核心类库在jdk文件下/jre/lit/rt.jar文件中,可以解压查看。

 

Extension:

        扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或这有java.ext.dirs系统属性指定的目录)中的jar包。

        通过这种方式可以为Java扩展核心类以外的新功能,把自己开发的类打成jar包,放到JAVA_HOME/jre/lib/ext路径下即可。

 

System:

        系统类加载器,它负责在JVM启动时加载来自Java命令的-ClassPath选项。java.class.path系统属性或CLASSPATH环境变量所指定的JAR包和类路径。

 

JAVA类加载机制:

        Java类加载机制一般采用的是“双亲委托”,当需要加载一个类时子类加载器会委托给自己的父类,这样层层向上直到根类加载器,如果要加载的类在根类加载器中有就加载返回,如果没有则向下寻找直至最后一层子类加载器,如果也没有就会返回ClassNotFoundException。

 

Tomcat类加载器:tomcat类加载器在JAVA类加载器的基础上进行了扩展,具体结构如下:

 

        其中WebApp以上层的tomcat类加载器还是遵守双亲委托机制,而每个WebApp有自己的类加载器,所以tomcat的类加载机制有一定的特殊性。

         1、  WebApp的独立性:假如在WebApp1中有一个test类,同时在Common中也有一个test类,在启动程序是WebApp会加载自己的test类而不是向上级common请求。这一点很像面向对象中子类和父类的关系。如果子类重写了父类的方法那么子类对象在调用时使用自己的方法,如果没有重写则调用父类的方法。

        2、  父类加载器不能使用WebAPP中的类,这个在DRP项目中就有所体现,在将数据库连接更换为数据库连接池的时报了一个这样的错“Cannot load JDBC class ’ oracle.jdbc.driver.OracleDriver’”,因为在更换数据库连接池时使用了java的JNDI服务,JNDI寻找类的路径不在WebApp中,所以jdbc的jar包虽然我们在最开始的时候已经拷贝到了我们项目中还是回报找不到驱动类的错误。

小结:

        Java的加载机制防止程序中的类覆盖java本身的类,也是一种安全机制。把java类加载机制弄明白很多错误就知道怎么解决,也可以避免一些不必要的错误。

评论 47
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值