Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 311|回复: 0

[Java基础知识]Java类装载机制要义

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-2 06:14:41 | 显示全部楼层 |阅读模式
    基本原理  
            所有类都由类装载器载入,载入内存中的类对应一个 java.lang.Class 实例。
      已被加载的类由该类的类加载器实例与该类的全路径名的组合标识。设有 packagename.A Class ,分别被类加载器 CL1 和 CL2 加载,则系统中有两个不同的 java.lang.Class 实例:
    <CL1, packagename.A> 和 <CL2, packagename.A> 。
                                                                                          
          存在一个 Bootstrap Loader (以下简称为 BL ),由 C++写成,负责在虚拟机启动后一次性加载 Java 基础类库中的所有类。其他的类装载器由 Java 写成,都是 java.lang.ClassLoader 的子类。除 BL 之外的所有类装载器都有一个 parent 属性,指向其父装载器。查阅 java.lang.ClassLoader 的源码,不难发现类装载器的委托装载方式。  
      
      
       
       
         
          
               protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
                   {  
                         // First, check if the class has already been loaded  
                         Class c = findLoadedClass(name);  
                         if (c == null ) {  
                             try {  
                                  if ( parent != null ) {  
                                      c = parent .loadClass(name, false );  
                                  } else {  
                                      c = findBootstrapClass0(name);  
                                  }  
                             } catch (ClassNotFoundException e) {  
                                 // If still not found, then invoke findClass in order  
                                 // to find the class.  
                                 c = findClass(name);  
                             }  
                         }  
                         if (resolve) {  
                             resolveClass(c);  
                         }  
                         return c;  
                   }  
          
         
               对于给定的类名,首先检查自己是否已加载过该类。如果没有,则首先通过父装载器加载(如果 parent==null ,则直接通过 BL 来加载,相当于 BL 是其父装载器)。如果父装载器也无法装载,才真正调用自己的 findClass() 方法来装载。
             Java 基础类在 Java 虚拟机启动后由 BL一次性载入。构成 Java 应用程序的其它类在程序运行过程中由不同类装载器按需通过 loadClass() 方法装载。  Java 程序启动过程中的类装载器  当执行“ java XXX.class ”时, java.exe 首先找到 JRE ( Java Runtime Environment ),接着找到位于 JRE 之中的 JVM.dll ,最后载入 jvm.dll 并启动虚拟机。  虚拟机一启动,先做一些初始化动作,如获取系统参数等,然后产生 BL 。 BL 加载 Java 基础类,这些类都存放在 JRE 中的 lib 目录下,可由 System.getProperty(“sun.boot.class.path”) 列出,如:
      
       
         
          
          C:Program FilesJavajre1.5.0_09lib
    t.jar;  C:Program FilesJavajre1.5.0_09libi18n.jar;  C:Program FilesJavajre1.5.0_09libsunrsasign.jar;  C:Program FilesJavajre1.5.0_09libjsse.jar;  C:Program FilesJavajre1.5.0_09libjce.jar;  C:Program FilesJavajre1.5.0_09libcharsets.jar;  C:Program FilesJavajre1.5.0_09classes  
          
         
       
            BL 然后创建 sun.misc.Launcher$ExtClassLoader ( ExtClassLoader 是定义于 sun.misc.Launcher 之内的内部类,继承自 java.lang.URLClassLoader )的实例(以下简称 EL )和 sun.misc.Launcher$AppClassLoader ( AppClassLoader 是定义于 sun.misc.Launcher 之内的内部类,继承自 URLClassLoader )的实例(以下简称 AL ),并将 EL 的 parent 属性设置为 null , AL 的 parent 属性设置为 EL 。
             EL 在程序运行过程中按需加载保存在 JRE 的“ libext ”目录下的类。该目录可由 System.getProperty(“java.ext.dirs”) 读出,如
      
       
         
          
          C:Program FilesJavajre1.5.0_09libext  
          
         
       
            AL 在程序运行过程中按需加载的类搜索路径则是从系统参数 java.class.path 取出的字符串。 java.class.path 是由我们在执行 java.exe 时,利用 -cp 或 -classpath 或 CLASSPATH 环境变量所决定。我们应用程序用到的非 JRE 提供类的搜索路径一般都配置在 java.class.path 中。  什么时候装载类,由什么类装载器装载  1.  Java 基础类由 BL 在虚拟机启动时一次性载入。  2.  包含 main() 的入口类由 AL 的 loadClass() 方法载入。  3.  由 new 关键字创建一个类的实例。该类由包含该 new 语句的类的类装载器( ClassLoader.getCallerClassLoader() )的 loadClass() 方法载入。  4.  调用 Class.forName() 方法。完整的 forName() 函数版本有一个 ClassLoader 参数,用于指定用什么类装载器来装载指定类。
      
       
         
          
              public static Class<?> forName(String name, boolean initialize,  
                                ClassLoader loader) throws ClassNotFoundException  
               
          
         
       
            对于 public static Class<?> forName(String className) 版本,是由包含该语句的类的类装载器( ClassLoader.getCallerClassLoader() )的 loadClass() 方法载入。
      5.  调用某个 ClassLoader 实例的 loadClass() 方法。通过该 ClassLoader 实例的 loadClass() 方法载入。应用程序可以通过继承在 ClassLoader 实现自己的类装载器。  
           6 .装载一个类时,首先要装载该类的基类及其接口。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-27 01:59 , Processed in 0.362180 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表